home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / graphics / gifmachn / part01 next >
Encoding:
Internet Message Format  |  1991-02-18  |  69.8 KB

  1. Path: news.larc.nasa.gov!amiga-request
  2. From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v91i014: GIFMachine 2.116 - convert GIF images into IFF SHAMs, Part01/02
  4. Reply-To: caw@miroc.chi.il.us (Christopher A. Wichura)
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v91i014@ab20.larc.nasa.gov>
  7. Date: 18 Feb 91 21:19:03 GMT
  8. Approved: tadguy@uunet.UU.NET (Tad Guy)
  9. X-Mail-Submissions-To: amiga@uunet.uu.net
  10. X-Post-Discussions-To: comp.sys.amiga.misc
  11.  
  12. Submitted-by: caw@miroc.chi.il.us (Christopher A. Wichura)
  13. Posting-number: Volume 91, Issue 014
  14. Archive-name: graphics/gifmachine2116/part01
  15.  
  16. [ uuencoded executable, help_txt, and two .o files included  ...tad ]
  17.  
  18. This is an update to v2.104 (available on fish #404 (405?) and recently
  19. distributed via comp.{binaries/sources}.amiga).  It fixes a couple things
  20. in the iff writer that have recently been reported to me.  The ReadMeFirst
  21. file explains these changes.
  22.  
  23. -=> CAW
  24.  
  25.  
  26.  
  27. #!/bin/sh
  28. # This is a shell archive.  Remove anything before this line, then unpack
  29. # it by saving it into a file and typing "sh file".  To overwrite existing
  30. # files, type "sh file -c".  You can also feed this as standard input via
  31. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  32. # will see the following message at the end:
  33. #        "End of archive 1 (of 2)."
  34. # Contents:  GIFMachine.docs ReadMeFirst Sources Sources/24to12.c
  35. #   Sources/GIFMachine.h Sources/arg_help.o.uu Sources/arg_help.uu
  36. #   Sources/doflip.c Sources/doimage.c Sources/extensions.c
  37. #   Sources/giftosham.c Sources/largearrays.c Sources/lmkfile
  38. #   Sources/mymem.c Sources/myprintf.c Sources/rgbdiff.c
  39. #   Sources/startup.a Sources/stripborder.c Sources/version.o.uu
  40. #   Sources/warncli.c Sources/writeiff.c Sources/xcomp.c
  41. # Wrapped by tadguy@ab20 on Mon Feb 18 16:18:59 1991
  42. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  43. if test -f 'GIFMachine.docs' -a "${1}" != "-c" ; then 
  44.   echo shar: Will not clobber existing file \"'GIFMachine.docs'\"
  45. else
  46. echo shar: Extracting \"'GIFMachine.docs'\" \(8774 characters\)
  47. sed "s/^X//" >'GIFMachine.docs' <<'END_OF_FILE'
  48. X
  49. X                                GIFMachine
  50. X
  51. X                 Copyright 1990 by Christopher A. Wichura
  52. X                           (caw@miroc.chi.il.us)
  53. X
  54. X
  55. XLegal mumbo jumbo:
  56. X
  57. XGIFMachine is not in the public domain.  All source files, along with the
  58. Xresulting executable, are copyright by C. Wichura.  You may not sell
  59. XGIFMachine.  The only allowed charge that may be placed on GIFMachine is
  60. Xfor media and/or mailing costs.
  61. X
  62. XGIFMachine may be freely redistributed via BBSs, InterNet/Usenet, and disk
  63. Xlibraries such as Fred Fish's, as long as the archive is not modified.
  64. XDisk magazines and services that charge extra for file transfers may not
  65. Xdistribute GIFMachine.
  66. X
  67. XIn using GIFMachine, you accept the responsibility for any damage or loss of
  68. Xproductivity/money that may occur through or during its use.  C. Wichura is
  69. Xnot and can not be held accountable.
  70. X
  71. X                            What is GIFMachine?
  72. X                            ~~~~~~~~~~~~~~~~~~~
  73. XGIFMachine is a program that converts pictures stored in the CompuServe GIF
  74. X(Graphics Interchange Format) format into IFF SHAM format.  There are very
  75. Xfew programs that do this, and most have many problems (not that GIFMachine
  76. Xdoesn't either -- see below).
  77. X
  78. XFor a long time, I used a program called ShamSharp to convert GIFs to IFF
  79. Xformat.  ShamSharp was the only thing I would even consider using (execpt
  80. Xfor ASDG's The Art Department, a very fine commercial product!).  However,
  81. Xthere were a number of things about it that irked me.
  82. X
  83. X   1)  If a picture had >16 colours and a width >320, ShamSharp would
  84. X       __ALWAYS__ halve the width of the image.  Not only that, but it
  85. X       did so by simply skipping every other pixel of the original GIF.
  86. X       This resulted in a tremendous loss in resolution.
  87. X
  88. X       I, myself, would rather have the entire picture converted and be
  89. X       able to use my favorite viewer (Mostra, by S. Vigna) to scroll
  90. X       around the image.  Thus, by default, GIFMachine will not halve
  91. X       the picture's width.  There is a command line switch to make it
  92. X       do so, however, in which case it actually thinks about it a bit
  93. X       rather than just dropping the odd pixels.
  94. X
  95. X   2)  If an image had more than 400 lines in it, ShamSharp would
  96. X       GURU the system if the SHAM mode flag was used.  GIFMachine handles
  97. X       large pictures well (that was one of the primary concerns I had
  98. X       while writing it) and has been tested with images as large as
  99. X       1152x890!
  100. X
  101. X   3)  ShamSharp would write bad IFF files for me on a regular basis.  I
  102. X       suspect this is because of some subtle bug in the cmpByteRun1
  103. X       compression routine ShamSharp uses.  Anyway, GIFMachine has yet to
  104. X       write a bad IFF on me.  (Cross Fingers, Cross Fingers :-)
  105. X
  106. XGIFMachine also offers the user the ability to automatically remove a
  107. Xborder area in a picture, among its other toys.  (I just hate it when you
  108. Xhave an image floating in the middle of the screen with inches of nothing
  109. Xaround it.)
  110. X
  111. X                          Drawbacks of GIFMachine
  112. X                          ~~~~~~~~~~~~~~~~~~~~~~~
  113. XIf you are looking for speed, go someplace else.  GIFMachine was written
  114. Xwith the idea of getting the best possible image from a GIF file, not as
  115. Xsomething to view GIFs in a quick and dirty manner.  Usually what I do is
  116. Xuse something like HAMGIF to see if the GIF is actually worth the effort
  117. Xand then convert a series of GIFs in one shot by specifying multiple
  118. Xfilepspecs.  On a stock 500, the average picture takes around 25 minutes to
  119. Xconvert (half that if the image is interlaced, which is often the case when
  120. Xthe width is halved).
  121. X
  122. XGIFMachine knows how to write only one thing: SHAMs.  If a picture only
  123. Xuses <= 16 colours, SHAM is not needed.  It would be much faster to write a
  124. Xnormal IFF and skip the SHAM conversion calculations.  In such a case, it
  125. Xwould be better to go back and use something like ShamSharp.  (Note that
  126. Xthis has changed with GIFMachine v2:  You can now write 24bit deep ILBMs as
  127. Xwell.)
  128. X
  129. XThe only viewer I know of that properly handles SHAMs with >400 lines is
  130. XMostra.  SuperSham 3.2 (?) will display the image, but does not allow
  131. Xscrolling around.  The latest version of Christian Weber's ShowIFF
  132. X(included in the v18.? distribution of his iff.library) will also display
  133. XSHAMs and let one scroll around.  However, he does not rebuild the copper
  134. Xlist during vertical scrolling and thus the image turns to muck if one
  135. Xscrolls down.
  136. X
  137. X                             Using GIFMachine
  138. X                             ~~~~~~~~~~~~~~~~
  139. XGIFMachine requires that you have KickStart 2.0 or greater (hey, I have a
  140. X3000 and SAS C with 2.0 includes so I dumped ARP in favor of 2.0).  It also
  141. Xrequires a fair amount of RAM (though it does not have to be CHIP RAM or
  142. Xcontiguous).  Alas, memory requirements have gone up with v2; the primary
  143. Ximage now requires three bytes to store a pixel instead of two.   A 640x480
  144. XGIF now requires about a meg of free memory to convert.
  145. X
  146. XGIFMachine uses the 2.0 ReadArgs() argument parser.  Thus, one can always
  147. Xenter `GIFMachine ?' on the command line for help.  GIFMachine can not be
  148. Xrun from the WorkBench.
  149. X
  150. XGIFMachine accepts the following arguments:
  151. X
  152. X<filespec1> ... <filespecN> [TO <directory or filespec>] [ALL]
  153. X                            [NOBORDER <line thresh>] [XCOMP] [DITHER]
  154. X                            [XFLIP] [YFLIP] [DEEP] [BUFSIZE <Size in KBytes>]
  155. X
  156. XEach filespec may contain any valid 2.0 wildcards (really regular
  157. Xexpressions).
  158. X
  159. XThe TO option allows one to specify where to put the IFFs.  If not given,
  160. Xthey will be placed in the current directory.  It is generally advised that
  161. XTO point at a directory.  However, if you are converting only a single GIF
  162. Xfile then there is no reason one can not specify a full filespec.
  163. X
  164. XThe ALL option will cause GIFMachine to recursively descend into any
  165. Xdirectories while matching filespecs.
  166. X
  167. XThe NOBORDER option instructs GIFMachine to remove the border area from an
  168. Ximage.  It takes, as its <line thresh> parameter, an integer between 0 and
  169. X100 that indicates what percentage of a line can differ from the border
  170. Xcolour and still have the line removed.  This option has been slightly
  171. Xmodified in the v2 release:  Before, GIFMachine assumed that the value at
  172. Xcoordinate 0,0 was the colour of the entire border area.  This is not
  173. Xalways the case, however.  Take, for example, a GIF with the image right up
  174. Xin the upper left corner with a large empty region to the right and below
  175. Xof it.  Such an image would have almost none of the offending border
  176. Xremoved.  GIFMachine will now attempt to run the stripper four times, using
  177. Xeach of the four corners' colour for the border check.  For the most part,
  178. Xthis does not slow this function down because a border check is aborted as
  179. Xsoon as the <line thresh> is exceeded and GIFMachine moves to the next
  180. Xcorner.
  181. X
  182. XThe next option, XCOMP, tells GIFMachine to halve the width of images.
  183. X
  184. XWhen the DITHER option is specified, a boustrophedonic Floyd-Steinberg
  185. Xerror diffusion algorythm will be used when reducing the colour palette to
  186. X12 bits.  This can help eliminate colour banding that occurs in places
  187. Xwhere subtle shadows occur.
  188. X
  189. XThe XFLIP and YFLIP options will flip the image horizontally and
  190. Xvertically, respectively.
  191. X
  192. XThe DEEP option will cause GIFMachine to write a 24bit deep ILBM instead of
  193. Xa SHAM file.  The DITHER option will be ignored in this mode, however.
  194. XWriting deep ILBMs if much faster than writing SHAMs because no
  195. Xcomputations need to be made.  Please note that files written with this
  196. Xoption in effect can be quite large.  Expect a 640x480 XCOMPed image to be
  197. Xover 400k in length, for example.
  198. X
  199. XThe final option, BUFSIZE, allows one to change the read buffer size used
  200. Xwhen decompressing GIFs.  It defaults to two Kbytes.  The argument is
  201. Xspecified in number of Kbytes, not bytes.  Thus, if you have memory to burn
  202. Xand want a large buffer you could specify a BUFSIZE 100 and you would get a
  203. Xbuffer 100k in size.  This command does not effect the writing of the IFF
  204. Xfile, however.
  205. X
  206. XNote that if GIFMachine determines that the image can be written interlaced
  207. X(depends on aspect ratios) then it will work on two lines at a time instead
  208. Xof one.  This is because the SHAM format only changes the base colours
  209. Xevery other line when displaying interlaced images.
  210. X
  211. XGIFMachine and GIF89a compatibility:  GIFMachine should be able to read any
  212. XGIF file written under the GIF89a specs.  GIFMachine does not, however,
  213. Xperform aspect corrections or process Plain Text Extensions (for obvious
  214. Xreasons), Graphic Control Extensions, or Application Extensions.
  215. XGIFMachine will, however, detect the new Comment Extension blocks.  The
  216. Xmessages contained in such blocks will be stored and output as ANNO chunks
  217. Xwhen the IFF file is being written.
  218. X
  219. X-=> CAW
  220. END_OF_FILE
  221. if test 8774 -ne `wc -c <'GIFMachine.docs'`; then
  222.     echo shar: \"'GIFMachine.docs'\" unpacked with wrong size!
  223. fi
  224. # end of 'GIFMachine.docs'
  225. fi
  226. if test -f 'ReadMeFirst' -a "${1}" != "-c" ; then 
  227.   echo shar: Will not clobber existing file \"'ReadMeFirst'\"
  228. else
  229. echo shar: Extracting \"'ReadMeFirst'\" \(1221 characters\)
  230. sed "s/^X//" >'ReadMeFirst' <<'END_OF_FILE'
  231. XThis is version 2.104, an update to version 2.96.  It fixes a bug in the
  232. XStripBorder() routine which could cause the system to crash (it actually
  233. Xappears to be more a bug in SAS 5.10's conditional code creation).
  234. X
  235. XI also reduced the amount of static memory declared by 1k.  Also moved some
  236. Xof the declarations in giftosham.c to largearrays.c to avoid the `too much
  237. Xglobal data' warning.
  238. X
  239. X---------------------------------------------------------------------------
  240. X2/24/91:  Version 2.116
  241. X
  242. XThis fixes a couple problems with the iff writer:
  243. X
  244. X    1)  If the image had an odd width and was not XCOMPed or
  245. X        NOBORDERed, a corrupted iff file would be written.
  246. X
  247. X    2)  If the image was greater vertically than the size of one's
  248. X        screen (i.e., required scrolling down), was of odd height,
  249. X        and was interlaced, Mostra v1.02 would glitch when one
  250. X        scrolled all the way down to the bottom of the image.
  251. X        This has been fixed by writing an extra blank scan line
  252. X        to images of odd height.
  253. X
  254. X
  255. XI also moved the help text into a seperate file which is then BLinked in.
  256. XMakes it easier to edit, and doesn't cause the compiler to throw ten
  257. Xthousand coniption fits (i.e., crash) when it gets to be more than 512
  258. Xchars long.
  259. END_OF_FILE
  260. if test 1221 -ne `wc -c <'ReadMeFirst'`; then
  261.     echo shar: \"'ReadMeFirst'\" unpacked with wrong size!
  262. fi
  263. # end of 'ReadMeFirst'
  264. fi
  265. if test ! -d 'Sources' ; then
  266.     echo shar: Creating directory \"'Sources'\"
  267.     mkdir 'Sources'
  268. fi
  269. if test -f 'Sources/24to12.c' -a "${1}" != "-c" ; then 
  270.   echo shar: Will not clobber existing file \"'Sources/24to12.c'\"
  271. else
  272. echo shar: Extracting \"'Sources/24to12.c'\" \(4024 characters\)
  273. sed "s/^X//" >'Sources/24to12.c' <<'END_OF_FILE'
  274. X/* Copyright 1990 by Christopher A. Wichura.
  275. X   See file GIFMachine.doc for full description of rights.
  276. X*/
  277. X
  278. X#include "GIFMachine.h"
  279. X
  280. Xextern struct GIFdescriptor gdesc;
  281. XEXTERNBITPLANE;
  282. X
  283. X/* since both MasterColourTable and the PaletteBuf are the same size and
  284. X   type we will define MCT to be the PaletteBuf to cut down on static
  285. X   memory declarations */
  286. X#define MasterColourTable PaletteBuf
  287. X
  288. Xextern UBYTE MasterColourTable[MAXCOLOURS];
  289. Xstatic UWORD TotalColours;
  290. X
  291. Xextern BYTE *CurrentLineErr[3];
  292. Xextern BYTE *LastLineErr[3];
  293. X
  294. Xextern char *AbortMsg;
  295. X
  296. X#define MAXERR 2
  297. X
  298. Xvoid ReduceTo12(void)
  299. X{
  300. X    register UWORD x;
  301. X    register UWORD y;
  302. X
  303. X    PutStr("...Reducing palette to 12 bits.\n......Line ");
  304. X
  305. X    TotalColours = 0;
  306. X    memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
  307. X
  308. X    for (y = 0; y < gdesc.gd_Height; y++) {
  309. X        MyPrintf("%5ld", y);
  310. X
  311. X        if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  312. X            MyPrintf("\n%s", AbortMsg);
  313. X            MyExit(ABORTEXITVAL);
  314. X        }
  315. X
  316. X        for (x = 0; x < gdesc.gd_Width; x++)
  317. X            PutValue(x, y, AddColour(&BitPlane[y][x]));
  318. X
  319. X        PutStr("\x9B" "5D");
  320. X    }
  321. X
  322. X    MyPrintf("\x9B" "5D%ld total unique colours used.\n", TotalColours);
  323. X}
  324. X
  325. Xvoid DitherTo12(void)
  326. X{
  327. X    register UWORD x;
  328. X    register UWORD y;
  329. X    register int RedErr;
  330. X    register int GreenErr;
  331. X    register int BlueErr;
  332. X    BYTE **cerr, **lerr, **terr;
  333. X    struct RGB rgb;
  334. X
  335. X    PutStr("...Dithering palette to 12 bits.\n......Setup");
  336. X
  337. X    TotalColours = 0;
  338. X    memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
  339. X
  340. X    cerr = (BYTE **)&CurrentLineErr[0];
  341. X    lerr = (BYTE **)&LastLineErr[0];
  342. X
  343. X    /* the top, left and right borders will be used unmodified */
  344. X
  345. X    for (x = 0; x < gdesc.gd_Width; x++)
  346. X        PutValue(x, 0, AddColour(&BitPlane[0][x]));
  347. X
  348. X    for (y = 1; y < gdesc.gd_Height; y++) {
  349. X        PutValue(0, y, AddColour(&BitPlane[y][0]));
  350. X        PutValue(gdesc.gd_Width - 1, y, AddColour(&BitPlane[y][gdesc.gd_Width - 1]));
  351. X    }
  352. X
  353. X    /* since the error tables are alloced with MEMF_CLEAR we won't bother
  354. X       to clear them here.  instead, we just hit the main loop */
  355. X
  356. X    PutStr("\x9B" "5DLine ");
  357. X
  358. X    for (y = 1; y < gdesc.gd_Height; y++) {
  359. X        MyPrintf("%5ld", y);
  360. X
  361. X        if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  362. X            MyPrintf("\n%s", AbortMsg);
  363. X            MyExit(ABORTEXITVAL);
  364. X        }
  365. X
  366. X        for (x = 1; x < (gdesc.gd_Width - 1); x++) {
  367. X            rgb = BitPlane[y][x];
  368. X
  369. X            RedErr   = cerr[0][x - 1] + 7*lerr[0][x - 1] + 5*lerr[0][x] + 3*lerr[0][x + 1];
  370. X            GreenErr = cerr[1][x - 1] + 7*lerr[1][x - 1] + 5*lerr[1][x] + 3*lerr[1][x + 1];
  371. X            BlueErr  = cerr[2][x - 1] + 7*lerr[2][x - 1] + 5*lerr[2][x] + 3*lerr[2][x + 1];
  372. X
  373. X            RedErr   >>= 4;
  374. X            GreenErr >>= 4;
  375. X            BlueErr  >>= 4;
  376. X
  377. X    /* now we add the errors into the colour we want.  if this would push
  378. X       us over 255 (and thus out of range) we subtract the error out so
  379. X       that we still see some dithering instead of washing out the area. */
  380. X
  381. X            if (rgb.rgb_Red + RedErr > 255)
  382. X                rgb.rgb_Red -= RedErr;
  383. X            else
  384. X                rgb.rgb_Red += RedErr;
  385. X
  386. X            if (rgb.rgb_Green + GreenErr > 255)
  387. X                rgb.rgb_Green -= GreenErr;
  388. X            else
  389. X                rgb.rgb_Green += GreenErr;
  390. X
  391. X            if (rgb.rgb_Blue + BlueErr > 255)
  392. X                rgb.rgb_Blue -= BlueErr;
  393. X            else
  394. X                rgb.rgb_Blue += BlueErr;
  395. X
  396. X            PutValue(x, y, AddColour(&rgb));
  397. X
  398. X            RedErr   = (int)rgb.rgb_Red   - (int)(rgb.rgb_Red   & 0xF0);
  399. X            GreenErr = (int)rgb.rgb_Green - (int)(rgb.rgb_Green & 0xF0);
  400. X            BlueErr  = (int)rgb.rgb_Blue  - (int)(rgb.rgb_Blue  & 0xF0);
  401. X
  402. X            if (RedErr > MAXERR)
  403. X                RedErr = (RedErr * 3) >> 2;
  404. X
  405. X            if (GreenErr > MAXERR)
  406. X                GreenErr = (GreenErr * 3) >> 2;
  407. X
  408. X            if (BlueErr > MAXERR)
  409. X                BlueErr = (BlueErr * 3) >> 2;
  410. X
  411. X            cerr[0][x] = RedErr;
  412. X            cerr[1][x] = GreenErr;
  413. X            cerr[2][x] = BlueErr;
  414. X        }
  415. X
  416. X            terr = lerr;
  417. X            lerr = cerr;
  418. X            cerr = terr;
  419. X
  420. X        PutStr("\x9B" "5D");
  421. X    }
  422. X
  423. X    MyPrintf("\x9B" "5D%ld total unique colours used.\n", TotalColours);
  424. X}
  425. X
  426. XUWORD AddColour(struct RGB *rgb)
  427. X{
  428. X    register UWORD colour;
  429. X
  430. X    colour = ((rgb->rgb_Red << 4) & 0xF00) |
  431. X         (rgb->rgb_Green & 0xF0) |
  432. X         (rgb->rgb_Blue >> 4);
  433. X
  434. X    if (!MasterColourTable[colour]) {
  435. X        MasterColourTable[colour] = 1;
  436. X        TotalColours++;
  437. X    }
  438. X
  439. X    return colour;
  440. X}
  441. END_OF_FILE
  442. if test 4024 -ne `wc -c <'Sources/24to12.c'`; then
  443.     echo shar: \"'Sources/24to12.c'\" unpacked with wrong size!
  444. fi
  445. # end of 'Sources/24to12.c'
  446. fi
  447. if test -f 'Sources/GIFMachine.h' -a "${1}" != "-c" ; then 
  448.   echo shar: Will not clobber existing file \"'Sources/GIFMachine.h'\"
  449. else
  450. echo shar: Extracting \"'Sources/GIFMachine.h'\" \(2943 characters\)
  451. sed "s/^X//" >'Sources/GIFMachine.h' <<'END_OF_FILE'
  452. X/* Copyright 1990 by Christopher A. Wichura.
  453. X   See file GIFMachine.doc for full description of rights.
  454. X*/
  455. X
  456. X#include <exec/types.h>
  457. X#include <exec/lists.h>
  458. X#include <exec/nodes.h>
  459. X#include <proto/dos.h>
  460. X#include <proto/exec.h>
  461. X#include <string.h>
  462. X#include <stdlib.h>
  463. X
  464. X/* we only use this for testing purposes */
  465. Xvoid kprintf(UBYTE *, ...);
  466. X
  467. X/* some structures to make parsing the gif files a bit easier */
  468. Xstruct GIFdescriptor {
  469. X    UWORD gd_Width;
  470. X    UWORD gd_Height;
  471. X    UBYTE gd_ColInfo;
  472. X    UBYTE gd_BackGround;
  473. X    UBYTE gd_PixelAspect;    /* Aspect Ratio = (Pixel Aspect + 15) / 64 */
  474. X};
  475. X
  476. Xstruct ImageDesc {
  477. X    UWORD id_Left;
  478. X    UWORD id_Top;
  479. X    UWORD id_Width;
  480. X    UWORD id_Height;
  481. X    UBYTE id_Info;
  482. X};
  483. X
  484. Xstruct RGB {
  485. X    UBYTE rgb_Red;
  486. X    UBYTE rgb_Green;
  487. X    UBYTE rgb_Blue;
  488. X};
  489. X
  490. X#define GIF_IMAGE      0x2C
  491. X#define GIF_EXTENSION  0x21
  492. X#define GIF_TERMINATOR 0x3B
  493. X
  494. X#define GIF_COMMENT_EXT 0xFE
  495. X
  496. X#define MAXCOLOURS 4096
  497. X
  498. X/* these next macros are used to get the r, g, and b values of a given
  499. X   index */
  500. X#define GetRed(a)    (UBYTE)(a >> 8)
  501. X#define GetGreen(a)    (UBYTE)((a >> 4) & 0xF)
  502. X#define GetBlue(a)    (UBYTE)(a & 0xF)
  503. X
  504. X/* whenever we want to abort we will return this as our error code */
  505. X#define ABORTEXITVAL 1
  506. X
  507. X/* this struct is used to hold the linked list of comments found in the GIF
  508. X   file so that each can be written as a seperate ANNO chunk. */
  509. Xstruct CommentNode {
  510. X    struct MinNode cn_Node;
  511. X    char *cn_Comment;
  512. X    ULONG cn_CommentLength;
  513. X};
  514. X
  515. X/* function prototypes we use */
  516. Xextern int __regargs main(char *cmdptr, int cmdlen, struct WBStartup *WBMsg);
  517. Xextern void    WarnMustUseCLI(void);
  518. Xextern void    DoPattern(char *);
  519. Xextern void    Convert(char *);
  520. Xextern BOOL    IsDir(char *);
  521. Xextern void    FlipWord(UWORD *);
  522. Xextern BOOL    DoImage(BPTR);
  523. Xextern BOOL    DoExtension(BPTR);
  524. Xextern BOOL    WriteIFF(char *, BOOL);
  525. Xextern void    PutValue(UWORD, UWORD, UWORD);
  526. Xextern UWORD    GetValue(UWORD, UWORD);
  527. Xextern int    ReadCode(BPTR);
  528. Xextern void    AddPixel(UBYTE);
  529. Xextern void    StripBorder(void);
  530. Xextern BOOL    BorderCheck(UWORD, UWORD);
  531. Xextern void    DoXComp(void);
  532. Xextern void    GIFtoSHAM(void);
  533. Xextern void    InitDiff(void);
  534. Xextern ULONG    RGBdiff(UBYTE, UBYTE, UBYTE, UBYTE, UBYTE, UBYTE);
  535. Xextern void    OutDump(int);
  536. Xextern void    OutRun(int, int);
  537. Xextern void    InitMemory(void);
  538. Xextern char *    MyAlloc(ULONG);
  539. Xextern void    MyFree(char *);
  540. Xextern void    FreeAll(UWORD);
  541. Xextern void    MyExit(ULONG);
  542. Xextern void    DoXFlip(void);
  543. Xextern void    DoYFlip(void);
  544. Xextern void    ReduceTo12(void);
  545. Xextern void    DitherTo12(void);
  546. Xextern UWORD    AddColour(struct RGB *);
  547. Xextern void __stdargs MyPrintf(char *, ...);
  548. Xextern void __stdargs MySPrintf(char *, char *, ...);
  549. X
  550. X/* modules that want to use the Get/PutValue macros should include this
  551. X   next macro to externally reference the picture storage array */
  552. X#define EXTERNBITPLANE extern struct RGB **BitPlane
  553. X
  554. X/* for use once colour palette has been reduced to 12 bits */
  555. X#define GetValue(a, b) *((UWORD *)&BitPlane[b][a])
  556. X#define PutValue(a, b, c) *((UWORD *)&BitPlane[b][a]) = c
  557. END_OF_FILE
  558. if test 2943 -ne `wc -c <'Sources/GIFMachine.h'`; then
  559.     echo shar: \"'Sources/GIFMachine.h'\" unpacked with wrong size!
  560. fi
  561. # end of 'Sources/GIFMachine.h'
  562. fi
  563. if test -f 'Sources/arg_help.o.uu' -a "${1}" != "-c" ; then 
  564.   echo shar: Will not clobber existing file \"'Sources/arg_help.o.uu'\"
  565. else
  566. echo shar: Extracting \"'Sources/arg_help.o.uu'\" \(706 characters\)
  567. sed "s/^X//" >'Sources/arg_help.o.uu' <<'END_OF_FILE'
  568. Xbegin 666 arg_help.o
  569. XM```#YP````-A<F=?:&5L<"YO``````/H`````71E>'0```/I````925S('8EA
  570. XM<PI#;W!Y<FEG:'0@J2`Q.3DP(&)Y()LT.S,S.S0R;4-H<FES=&]P:&5R($$NE
  571. XM(%=I8VAU<F&;,#LS,SLT,&T@*)LS,FUC87>;,S-M0)LS,FUM:7)O8RYC:&DN@
  572. XM:6PN=7.;,S-M*0H*57-A9V4Z("`@("`E<R`\FS,Q;4=)1F9I;&5S*',IFS,RR
  573. XM;3X@6YLS,VU43R";,S%M1&ER96-T;W)Y('P@1FEL99LS,FU=(%N;,S-M04Q,`
  574. XMFS,R;5T*("`@("`@("`@("`@("`@("`@("`@(%N;,S-M3D]"3U)$15(@FS,R8
  575. XM;3R;,S%M3&EN92!4:')E<VB;,S)M/ET@6YLS,VU80T]-4)LS,FU=(%N;,S-M6
  576. XM1$E42$52FS,R;5T*("`@("`@("`@("`@("`@("`@("`@(%N;,S-M6$9,25";[
  577. XM,S)M72!;FS,S;5E&3$E0FS,R;5T@6YLS,VU$1450FS,R;5T@6YLS,VU"54930
  578. XM25I%()LS,FT\FS,Q;5-I>F4@:6X@2T)Y=&5SFS,R;3Y="ILS,6T````#[P$`2
  579. X:``-?87)G7VAE;'```````````````````_)S,
  580. X``
  581. Xend
  582. Xsize 476
  583. END_OF_FILE
  584. if test 706 -ne `wc -c <'Sources/arg_help.o.uu'`; then
  585.     echo shar: \"'Sources/arg_help.o.uu'\" unpacked with wrong size!
  586. fi
  587. # end of 'Sources/arg_help.o.uu'
  588. fi
  589. if test -f 'Sources/arg_help.uu' -a "${1}" != "-c" ; then 
  590.   echo shar: Will not clobber existing file \"'Sources/arg_help.uu'\"
  591. else
  592. echo shar: Extracting \"'Sources/arg_help.uu'\" \(606 characters\)
  593. sed "s/^X//" >'Sources/arg_help.uu' <<'END_OF_FILE'
  594. Xbegin 666 arg_help.txt
  595. XM)7,@=B5S"D-O<'ER:6=H=""I(#$Y.3`@8GD@FS0[,S,[-#)M0VAR:7-T;W!H2
  596. XM97(@02X@5VEC:'5R89LP.S,S.S0P;2`HFS,R;6-A=YLS,VU`FS,R;6UI<F]CV
  597. XM+F-H:2YI;"YU<YLS,VTI"@I5<V%G93H@("`@("5S(#R;,S%M1TE&9FEL97,HF
  598. XM<RF;,S)M/B!;FS,S;51/()LS,6U$:7)E8W1O<GD@?"!&:6QEFS,R;5T@6YLSC
  599. XM,VU!3$R;,S)M70H@("`@("`@("`@("`@("`@("`@("`@6YLS,VU.3T)/4D1%?
  600. XM4B";,S)M/)LS,6U,:6YE(%1H<F5S:)LS,FT^72!;FS,S;5A#3TU0FS,R;5T@_
  601. XM6YLS,VU$251(15*;,S)M70H@("`@("`@("`@("`@("`@("`@("`@6YLS,VU8^
  602. XM1DQ)4)LS,FU=(%N;,S-M649,25";,S)M72!;FS,S;41%15";,S)M72!;FS,SY
  603. XK;4)51E-)6D4@FS,R;3R;,S%M4VEZ92!I;B!+0GET97.;,S)M/ET*FS,Q;3,SB
  604. X``
  605. Xend
  606. Xsize 403
  607. END_OF_FILE
  608. if test 606 -ne `wc -c <'Sources/arg_help.uu'`; then
  609.     echo shar: \"'Sources/arg_help.uu'\" unpacked with wrong size!
  610. fi
  611. # end of 'Sources/arg_help.uu'
  612. fi
  613. if test -f 'Sources/doflip.c' -a "${1}" != "-c" ; then 
  614.   echo shar: Will not clobber existing file \"'Sources/doflip.c'\"
  615. else
  616. echo shar: Extracting \"'Sources/doflip.c'\" \(1470 characters\)
  617. sed "s/^X//" >'Sources/doflip.c' <<'END_OF_FILE'
  618. X/* Copyright 1990 by Christopher A. Wichura.
  619. X   See file GIFMachine.doc for full description of rights.
  620. X*/
  621. X
  622. X#include "GIFMachine.h"
  623. X
  624. Xextern struct GIFdescriptor gdesc;
  625. XEXTERNBITPLANE;
  626. X
  627. Xextern char *AbortMsg;
  628. X
  629. Xvoid DoXFlip(void)
  630. X{
  631. X    register UWORD x1;
  632. X    register UWORD x2;
  633. X    register UWORD y;
  634. X    struct RGB TempColourStore;
  635. X
  636. X    MyPrintf("...Flipping image %s.\n......%s ", "horizontally", "Line");
  637. X
  638. X        for (y = 0; y < gdesc.gd_Height; y++) {
  639. X        MyPrintf("%5ld", y);
  640. X
  641. X        for (x1 = 0, x2 = gdesc.gd_Width - 1; x1 < x2; x1++, x2--) {
  642. X            TempColourStore = BitPlane[y][x1];
  643. X            BitPlane[y][x1] = BitPlane[y][x2];
  644. X            BitPlane[y][x2] = TempColourStore;
  645. X        }
  646. X
  647. X        if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  648. X            MyPrintf("\n%s", AbortMsg);
  649. X            MyExit(ABORTEXITVAL);
  650. X        }
  651. X
  652. X        PutStr("\x9B" "5D");
  653. X    }
  654. X
  655. X    MyPrintf("\x9B" "%sDFlipped.    \n", "5");
  656. X}
  657. X
  658. Xvoid DoYFlip(void)
  659. X{
  660. X    register UWORD y1;
  661. X    register UWORD y2;
  662. X    register UWORD x;
  663. X    struct RGB TempColourStore;
  664. X
  665. X    MyPrintf("...Flipping image %s.\n......%s ", "vertically", "Column");
  666. X
  667. X        for (x = 0; x < gdesc.gd_Width; x++) {
  668. X        MyPrintf("%5ld", x);
  669. X
  670. X        for (y1 = 0, y2 = gdesc.gd_Height - 1; y1 < y2; y1++, y2--) {
  671. X            TempColourStore = BitPlane[y1][x];
  672. X            BitPlane[y1][x] = BitPlane[y2][x];
  673. X            BitPlane[y2][x] = TempColourStore;
  674. X        }
  675. X
  676. X        if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  677. X            MyPrintf("\n%s", AbortMsg);
  678. X            MyExit(ABORTEXITVAL);
  679. X        }
  680. X
  681. X        PutStr("\x9B" "5D");
  682. X    }
  683. X
  684. X    MyPrintf("\x9B" "%sDFlipped.    \n", "7");
  685. X}
  686. END_OF_FILE
  687. if test 1470 -ne `wc -c <'Sources/doflip.c'`; then
  688.     echo shar: \"'Sources/doflip.c'\" unpacked with wrong size!
  689. fi
  690. # end of 'Sources/doflip.c'
  691. fi
  692. if test -f 'Sources/doimage.c' -a "${1}" != "-c" ; then 
  693.   echo shar: Will not clobber existing file \"'Sources/doimage.c'\"
  694. else
  695. echo shar: Extracting \"'Sources/doimage.c'\" \(5352 characters\)
  696. sed "s/^X//" >'Sources/doimage.c' <<'END_OF_FILE'
  697. X/* Copyright 1990 by Christopher A. Wichura.
  698. X   See file GIFMachine.doc for full description of rights.
  699. X*/
  700. X
  701. X#include "GIFMachine.h"
  702. X
  703. Xextern struct GIFdescriptor gdesc;
  704. XEXTERNBITPLANE;
  705. X
  706. Xstatic struct ImageDesc idesc;
  707. Xextern struct RGB GlobalColourTable[256];
  708. Xstatic struct RGB LocalColourTable[256];
  709. Xextern ULONG ImageNumber;
  710. X
  711. Xextern char *AbortMsg;
  712. X
  713. Xstatic UWORD Xpos, Ypos;
  714. Xstatic BOOL interleave;
  715. X
  716. Xstatic UBYTE LeaveStep[5]  = {1, 8, 8, 4, 2};
  717. Xstatic UBYTE LeaveFirst[5] = {0, 0, 4, 2, 1};
  718. X
  719. X/* some variables used by the decompressor */
  720. Xstatic int ReadError;
  721. Xstatic UBYTE CodeSize;
  722. Xstatic int EOFCode;
  723. Xstatic UBYTE ReadMask;
  724. Xstatic int CompDataPointer;
  725. Xstatic int CompDataCount;
  726. Xstatic UBYTE CompData[256];
  727. X
  728. X/* tables used by the decompressor */
  729. Xstatic UWORD Prefix[4096];
  730. Xstatic UBYTE Suffix[4096];
  731. Xstatic UBYTE OutCode[1025];
  732. X
  733. XBOOL DoImage(BPTR fh)
  734. X{
  735. X    register int index;
  736. X    register int colours;
  737. X    int Code;
  738. X
  739. X    MyPrintf("...Image #%ld encountered.\n", ImageNumber++);
  740. X
  741. X    if (FRead(fh, (char *)&idesc, 1, 9) != 9) {
  742. X        PutStr("......Error reading image descriptor.\n");
  743. X        return TRUE;
  744. X    }
  745. X
  746. X    FlipWord(&idesc.id_Left);
  747. X    FlipWord(&idesc.id_Top);
  748. X    FlipWord(&idesc.id_Width);
  749. X    FlipWord(&idesc.id_Height);
  750. X
  751. X    interleave = idesc.id_Info & 1L << 6;
  752. X    if (interleave)
  753. X        interleave = 1;
  754. X
  755. X    MyPrintf("......Xpos from %ld to %ld, Ypos from %ld to %ld, %sinterlaced.\n",
  756. X        idesc.id_Left, idesc.id_Left + idesc.id_Width - 1,
  757. X        idesc.id_Top, idesc.id_Top + idesc.id_Height - 1,
  758. X        interleave ? "" : "not ");
  759. X
  760. X    if (idesc.id_Info & 1L << 7) {
  761. X        colours = 1L << ((idesc.id_Info & 7) + 1);
  762. X        MyPrintf("......Local colour map contains %ld entries.\n", colours);
  763. X
  764. X        for (index = 0; index < colours; index++) {
  765. X            if (FRead(fh, &LocalColourTable[index], 1, 3) != 3) {
  766. X                MyPrintf("......Error reading local colour #%ld.\n",
  767. X                    index);
  768. X                return TRUE;
  769. X            }
  770. X        }
  771. X    } else {
  772. X        colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
  773. X        CopyMem((char *)GlobalColourTable, (char *)LocalColourTable,
  774. X            sizeof(LocalColourTable));
  775. X    }
  776. X
  777. X    Xpos = Ypos = 0;
  778. X
  779. X    /* now we are ready to read the image in so do it! */
  780. X
  781. X    {
  782. X        int MaxCode, ClearCode, CurCode,
  783. X            OldCode, InCode, FreeCode;
  784. X        int OutCount;
  785. X        int FirstFree;
  786. X        UBYTE InitCodeSize, FinChar, BitMask;
  787. X
  788. X        MyPrintf("......Decompressing line number %5ld", Ypos);
  789. X
  790. X        /* get the codesize and do general setup for decompression */
  791. X        if ((CodeSize = FGetC(fh)) == -1) {
  792. X            PutStr("\n......I/O Error during decompression.\n");
  793. X            return TRUE;
  794. X        }
  795. X
  796. X        ClearCode = 1L << CodeSize;
  797. X        EOFCode = ClearCode + 1;
  798. X        FreeCode = FirstFree = ClearCode + 2;
  799. X
  800. X        CodeSize++;    /* per GIF spec */
  801. X        InitCodeSize = CodeSize;
  802. X        MaxCode = 1L << CodeSize;
  803. X        ReadError = ReadMask = OutCount = 0;
  804. X        CompDataPointer = CompDataCount = 0;
  805. X
  806. X        BitMask = colours - 1;
  807. X
  808. X        Code = ReadCode(fh);
  809. X        while (Code != EOFCode) {
  810. X            if (ReadError)
  811. X                return TRUE;
  812. X
  813. X            if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  814. X                MyPrintf("\n%s", AbortMsg);
  815. X                MyExit(ABORTEXITVAL);
  816. X            }
  817. X
  818. X            if (Code == ClearCode) {
  819. X                CodeSize = InitCodeSize;
  820. X                MaxCode = 1L << CodeSize;
  821. X                FreeCode = FirstFree;
  822. X                FinChar = CurCode = OldCode = Code = ReadCode(fh);
  823. X                AddPixel(FinChar);
  824. X            } else {
  825. X                CurCode = InCode = Code;
  826. X
  827. X                if (CurCode >= FreeCode) {
  828. X                    CurCode = OldCode;
  829. X                    OutCode[OutCount++] = FinChar;
  830. X                }
  831. X
  832. X                while (CurCode > BitMask) {
  833. X                    if (OutCount > 1024) {
  834. X                        PutStr("\n......Corrupt GIF file (OutCount)\n");
  835. X                        return TRUE;
  836. X                    }
  837. X
  838. X                    OutCode[OutCount++] = Suffix[CurCode];
  839. X                    CurCode = Prefix[CurCode];
  840. X                }
  841. X
  842. X                FinChar = CurCode;
  843. X                AddPixel(FinChar);
  844. X
  845. X                for (index = OutCount - 1; index >= 0; index--)
  846. X                    AddPixel(OutCode[index]);
  847. X                OutCount = 0;
  848. X
  849. X                Prefix[FreeCode] = OldCode;
  850. X                Suffix[FreeCode] = FinChar;
  851. X                OldCode = InCode;
  852. X
  853. X                if (++FreeCode >= MaxCode) {
  854. X                    if (CodeSize < 12) {
  855. X                        CodeSize++;
  856. X                        MaxCode <<= 1;
  857. X                    }
  858. X                }
  859. X            }
  860. X
  861. X            Code = ReadCode(fh);
  862. X        }
  863. X    }
  864. X
  865. X    if ((Code = FGetC(fh)) == -1)
  866. X        return TRUE;
  867. X
  868. X    /* done decompressing.  Erase decompressing message and exit */
  869. X    PutStr("\x9B" "22D\x9BKed.\n");
  870. X
  871. X    if (Code != 0) {
  872. X        PutStr("......Warning:  Unaligned packet.\n");
  873. X        UnGetC(fh, Code);
  874. X    }
  875. X
  876. X    return FALSE;
  877. X}
  878. X
  879. Xstatic UBYTE ByteBuf;
  880. X
  881. Xint ReadCode(BPTR fh)
  882. X{
  883. X    register int temp;
  884. X    register int DstMasked;
  885. X    register int DstMask;
  886. X    register LONG size;
  887. X
  888. X    temp = 0;
  889. X    DstMasked = 1L << CodeSize;
  890. X    for (DstMask = 1; DstMask != DstMasked; DstMask <<= 1) {
  891. X        if (!ReadMask) {
  892. X            if (CompDataPointer == CompDataCount) {
  893. X                if ((size = FGetC(fh)) == -1) {
  894. X                    PutStr("\n......I/O Error during decompression.\n");
  895. X                    ReadError = 1;
  896. X                    return EOFCode;
  897. X                }
  898. X
  899. X                if (FRead(fh, (char *)CompData, 1, size) != size) {
  900. X                    PutStr("\n......I/O Error during decompression.\n");
  901. X                    ReadError = 1;
  902. X                    return EOFCode;
  903. X                }
  904. X
  905. X                CompDataCount = size;
  906. X                CompDataPointer = 0;
  907. X            }
  908. X
  909. X            ReadMask = 1;
  910. X            ByteBuf = CompData[CompDataPointer++];
  911. X        }
  912. X
  913. X        if (ByteBuf & ReadMask)
  914. X            temp |= DstMask;
  915. X
  916. X        ReadMask <<= 1;
  917. X    }
  918. X
  919. X    return temp;
  920. X}
  921. X
  922. Xvoid AddPixel(UBYTE index)
  923. X{
  924. X    register UWORD XStore;
  925. X    register UWORD YStore;
  926. X
  927. X    XStore = Xpos + idesc.id_Left;
  928. X    YStore = Ypos + idesc.id_Top;
  929. X
  930. X    BitPlane[YStore][XStore] = LocalColourTable[index];
  931. X
  932. X    if (++Xpos == idesc.id_Width) {
  933. X        Xpos = 0;
  934. X        Ypos += LeaveStep[interleave];
  935. X        if (Ypos >= idesc.id_Height)
  936. X            Ypos = LeaveFirst[++interleave];
  937. X
  938. X        MyPrintf("\x9B" "5D%5ld", Ypos + idesc.id_Top);
  939. X    }
  940. X}
  941. END_OF_FILE
  942. if test 5352 -ne `wc -c <'Sources/doimage.c'`; then
  943.     echo shar: \"'Sources/doimage.c'\" unpacked with wrong size!
  944. fi
  945. # end of 'Sources/doimage.c'
  946. fi
  947. if test -f 'Sources/extensions.c' -a "${1}" != "-c" ; then 
  948.   echo shar: Will not clobber existing file \"'Sources/extensions.c'\"
  949. else
  950. echo shar: Extracting \"'Sources/extensions.c'\" \(2266 characters\)
  951. sed "s/^X//" >'Sources/extensions.c' <<'END_OF_FILE'
  952. X/* Copyright 1990 by Christopher A. Wichura.
  953. X   See file GIFMachine.doc for full description of rights.
  954. X*/
  955. X
  956. X#include "GIFMachine.h"
  957. X
  958. Xstruct MinList CommentList;
  959. Xstatic UBYTE buf[256];
  960. X
  961. XBOOL DoExtension(BPTR fh)
  962. X{
  963. X    register LONG size;
  964. X    register LONG cmdcode;
  965. X    register char *Comment;
  966. X    register char *OldComment;
  967. X    register int CommentLength;
  968. X    register int OldCommentLength;
  969. X    register struct CommentNode *cn;
  970. X
  971. X    if ((cmdcode = FGetC(fh)) == -1) {
  972. X        PutStr("...I/O error reading extension block function code\n");
  973. X        return TRUE;
  974. X    }
  975. X
  976. X    switch(cmdcode) {
  977. X        case GIF_COMMENT_EXT:
  978. X            PutStr("...Comment extension encountered.  Contents will be stored in an ANNO chunk.\n");
  979. X
  980. X            if (!(cn = (struct CommentNode *)MyAlloc(sizeof(struct CommentNode)))) {
  981. X                PutStr("......Out of memory allocating comment block.\n");
  982. X                return TRUE;
  983. X            }
  984. X
  985. X            Comment = NULL;
  986. X            CommentLength = 0;
  987. X
  988. X            for (;;) {
  989. X                if ((size = FGetC(fh)) == -1) {
  990. X                    PutStr("......I/O Error reading comment block.\n");
  991. X                    return TRUE;
  992. X                }
  993. X
  994. X                if (size) {
  995. X                    if (FRead(fh, buf, 1, size) != size) {
  996. X                        PutStr("......I/O Error reading comment block.\n");
  997. X                        return TRUE;
  998. X                    }
  999. X
  1000. X                    OldComment = Comment;
  1001. X                    OldCommentLength = CommentLength;
  1002. X                    CommentLength += size;
  1003. X
  1004. X                    if (!(Comment = MyAlloc(CommentLength))) {
  1005. X                        PutStr("......Out of memory allocating comment block.\n");
  1006. X                        return TRUE;
  1007. X                    }
  1008. X
  1009. X                    if (OldCommentLength) {
  1010. X                        CopyMem(OldComment, Comment, OldCommentLength);
  1011. X                        MyFree(OldComment);
  1012. X                    }
  1013. X
  1014. X                    CopyMem(buf, &Comment[OldCommentLength], size);
  1015. X                } else {    /* end of comment so store it */
  1016. X                    cn->cn_Comment = Comment;
  1017. X                    cn->cn_CommentLength = CommentLength;
  1018. X                    AddTail((struct List *)&CommentList, (struct Node *)cn);
  1019. X                    return FALSE;
  1020. X                }
  1021. X            }
  1022. X            break;
  1023. X
  1024. X        default:
  1025. X            MyPrintf("...Extension block function code #%ld not know, skipping.\n",
  1026. X             cmdcode);
  1027. X
  1028. X            /* we must skip over any data for the extension block */
  1029. X            for (;;) {
  1030. X                if ((size = FGetC(fh)) == -1) {
  1031. X                    PutStr("...I/O Error skipping unknown extension block.\n");
  1032. X                    return TRUE;
  1033. X                }
  1034. X
  1035. X                if (size == 0)
  1036. X                    return FALSE;
  1037. X
  1038. X                if (FRead(fh, buf, 1, size) != size) {
  1039. X                    PutStr("...I/O Error skipping unknown extension block.\n");
  1040. X                    return TRUE;
  1041. X                }
  1042. X            }
  1043. X            break;
  1044. X    }
  1045. X}
  1046. END_OF_FILE
  1047. if test 2266 -ne `wc -c <'Sources/extensions.c'`; then
  1048.     echo shar: \"'Sources/extensions.c'\" unpacked with wrong size!
  1049. fi
  1050. # end of 'Sources/extensions.c'
  1051. fi
  1052. if test -f 'Sources/giftosham.c' -a "${1}" != "-c" ; then 
  1053.   echo shar: Will not clobber existing file \"'Sources/giftosham.c'\"
  1054. else
  1055. echo shar: Extracting \"'Sources/giftosham.c'\" \(5180 characters\)
  1056. sed "s/^X//" >'Sources/giftosham.c' <<'END_OF_FILE'
  1057. X/* Copyright 1990 by Christopher A. Wichura.
  1058. X   See file GIFMachine.doc for full description of rights.
  1059. X*/
  1060. X
  1061. X#include "GIFMachine.h"
  1062. X
  1063. Xextern struct GIFdescriptor gdesc;
  1064. XEXTERNBITPLANE;
  1065. X
  1066. Xextern char *AbortMsg;
  1067. X
  1068. Xextern BOOL Laced;
  1069. X
  1070. XUWORD *SHAMmem;
  1071. X
  1072. Xstruct RGB Palette[16];
  1073. X
  1074. Xextern UBYTE PaletteBuf[MAXCOLOURS];
  1075. Xextern ULONG ColourBuf[MAXCOLOURS];
  1076. Xstatic ULONG ErrBuf[MAXCOLOURS];
  1077. X
  1078. X#define ISLACED (Laced && (y != gdesc.gd_Height - 1))
  1079. X
  1080. Xvoid GIFtoSHAM(void)
  1081. X{
  1082. X    register UWORD x;
  1083. X    register UWORD current;
  1084. X    register int index;
  1085. X    register int index2;
  1086. X    ULONG error;
  1087. X    UWORD y;
  1088. X    int Pal;
  1089. X    int ShamIndex;
  1090. X    int colours;
  1091. X
  1092. X    ULONG TotalErr, LineErr;
  1093. X
  1094. X    ULONG bestpal;
  1095. X    ULONG besterr;
  1096. X
  1097. X    UBYTE CurrentRed,  CurrentGreen,  CurrentBlue;
  1098. X    UBYTE PreviousRed, PreviousGreen, PreviousBlue;
  1099. X
  1100. X    MyPrintf("...Converting to SHAM format.\n......Line");
  1101. X
  1102. X    ShamIndex = TotalErr = 0;
  1103. X
  1104. X    /* palette zero is always the background colour.  regardless of
  1105. X       what the GIF specified for the background, we always use black.
  1106. X       this is a kludge to get around a hardware `feature' that causes
  1107. X       all overscanned screens to have a black background regardless
  1108. X       of what the background was specified to be.
  1109. X    */
  1110. X
  1111. X    Palette[0].rgb_Red = Palette[0].rgb_Green = Palette[0].rgb_Blue = 0;
  1112. X
  1113. X    for (y = 0; y < gdesc.gd_Height; y += (ISLACED ? 2 : 1)) {
  1114. X        if (ISLACED)
  1115. X            MyPrintf("s %5ld-%5ld", y, y + 1);
  1116. X        else
  1117. X            MyPrintf(" %5ld", y);
  1118. X
  1119. X        if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  1120. X            MyPrintf("\n%s", AbortMsg);
  1121. X            MyExit(ABORTEXITVAL);
  1122. X        }
  1123. X
  1124. X        memset((char *)ColourBuf, 0, sizeof(ColourBuf));
  1125. X
  1126. X        for (colours = index2 = 0; index2 < (ISLACED ? 2 : 1); index2++)
  1127. X            for (x = 0; x < gdesc.gd_Width; x++) {
  1128. X                current = GetValue(x, y + index2);
  1129. X
  1130. X                if (ColourBuf[current]++ == 0)
  1131. X                    colours++;
  1132. X            }
  1133. X
  1134. X        MyPrintf(", %4ld unique colours", colours);
  1135. X
  1136. X        memset((char *)PaletteBuf, 0, sizeof(PaletteBuf));
  1137. X
  1138. X        for (index = 0; index < MAXCOLOURS; index++) {
  1139. X            if (ColourBuf[index] == 0)
  1140. X                continue;
  1141. X
  1142. X            ErrBuf[index] = RGBdiff(GetRed(index),
  1143. X                        GetGreen(index),
  1144. X                        GetBlue(index),
  1145. X                        Palette[0].rgb_Red,
  1146. X                        Palette[0].rgb_Green,
  1147. X                        Palette[0].rgb_Blue);
  1148. X        }
  1149. X
  1150. X        for (Pal = 1; Pal < 16; Pal++) {
  1151. X            for (besterr = index = 0; index < MAXCOLOURS; index++) {
  1152. X                if (ColourBuf[index] == 0)
  1153. X                    continue;
  1154. X
  1155. X                if (ErrBuf[index] * ColourBuf[index] >= besterr) {
  1156. X                    bestpal = index;
  1157. X                    besterr = ErrBuf[index] * ColourBuf[index];
  1158. X                }
  1159. X            }
  1160. X
  1161. X            Palette[Pal].rgb_Red   = GetRed(bestpal);
  1162. X            Palette[Pal].rgb_Green = GetGreen(bestpal);
  1163. X            Palette[Pal].rgb_Blue  = GetBlue(bestpal);
  1164. X
  1165. X            for (index = 0; index < MAXCOLOURS; index++) {
  1166. X                if (ColourBuf[index] == 0)
  1167. X                    continue;
  1168. X
  1169. X                error = RGBdiff(GetRed(index),
  1170. X                        GetGreen(index),
  1171. X                        GetBlue(index),
  1172. X                        Palette[Pal].rgb_Red,
  1173. X                        Palette[Pal].rgb_Green,
  1174. X                        Palette[Pal].rgb_Blue);
  1175. X
  1176. X                if (error < ErrBuf[index]) {
  1177. X                    ErrBuf[index] = error;
  1178. X                    PaletteBuf[index] = Pal;
  1179. X                }
  1180. X            }
  1181. X        }
  1182. X
  1183. X        for (index = 0; index < 16; index++)
  1184. X            SHAMmem[ShamIndex++] = (UWORD)(
  1185. X                Palette[index].rgb_Red   << 8 |
  1186. X                Palette[index].rgb_Green << 4 |
  1187. X                Palette[index].rgb_Blue);
  1188. X
  1189. X        for (index2 = 0; index2 < (ISLACED ? 2 : 1); index2++) {
  1190. X            PreviousRed   = Palette[0].rgb_Red;
  1191. X            PreviousGreen = Palette[0].rgb_Green;
  1192. X            PreviousBlue  = Palette[0].rgb_Blue;
  1193. X
  1194. X            for (LineErr = x = 0; x < gdesc.gd_Width; x++) {
  1195. X                current = GetValue(x, y + index2);
  1196. X
  1197. X                CurrentRed   = GetRed(current);
  1198. X                CurrentGreen = GetGreen(current);
  1199. X                CurrentBlue  = GetBlue(current);
  1200. X
  1201. X                besterr = ErrBuf[current];
  1202. X                bestpal = PaletteBuf[current];
  1203. X
  1204. X                error = RGBdiff(
  1205. X                    CurrentRed,
  1206. X                    CurrentGreen,
  1207. X                    CurrentBlue,
  1208. X                    CurrentRed,
  1209. X                    PreviousGreen,
  1210. X                    PreviousBlue);
  1211. X
  1212. X                if (error < besterr) {
  1213. X                    besterr = error;
  1214. X                    bestpal = 16;
  1215. X                }
  1216. X
  1217. X                error = RGBdiff(
  1218. X                    CurrentRed,
  1219. X                    CurrentGreen,
  1220. X                    CurrentBlue,
  1221. X                    PreviousRed,
  1222. X                    CurrentGreen,
  1223. X                    PreviousBlue);
  1224. X
  1225. X                if (error < besterr) {
  1226. X                    besterr = error;
  1227. X                    bestpal = 17;
  1228. X                }
  1229. X
  1230. X                error = RGBdiff(
  1231. X                    CurrentRed,
  1232. X                    CurrentGreen,
  1233. X                    CurrentBlue,
  1234. X                    PreviousRed,
  1235. X                    PreviousGreen,
  1236. X                    CurrentBlue);
  1237. X
  1238. X                if (error < besterr) {
  1239. X                    besterr = error;
  1240. X                    bestpal = 18;
  1241. X                }
  1242. X
  1243. X                if (bestpal < 16) {
  1244. X                    PutValue(x, y + index2, bestpal);
  1245. X
  1246. X                    PreviousRed   = Palette[bestpal].rgb_Red;
  1247. X                    PreviousGreen = Palette[bestpal].rgb_Green;
  1248. X                    PreviousBlue  = Palette[bestpal].rgb_Blue;
  1249. X                } else if (bestpal == 16) {
  1250. X                    PutValue(x, y + index2, CurrentRed | 0x20);
  1251. X
  1252. X                    PreviousRed = CurrentRed;
  1253. X                } else if (bestpal == 17) {
  1254. X                    PutValue(x, y + index2, CurrentGreen | 0x30);
  1255. X
  1256. X                    PreviousGreen = CurrentGreen;
  1257. X                } else {
  1258. X                    PutValue(x, y + index2, CurrentBlue | 0x10);
  1259. X
  1260. X                    PreviousBlue = CurrentBlue;
  1261. X                }
  1262. X
  1263. X                LineErr += besterr;
  1264. X            }
  1265. X
  1266. X            TotalErr += LineErr;
  1267. X        }
  1268. X
  1269. X        MyPrintf("\x9B" "%sD\x9BK", (ISLACED ? "34" : "27"));
  1270. X    }
  1271. X
  1272. X    {
  1273. X        ULONG    ErrPerPixel;
  1274. X        char    TextBuf[10];
  1275. X
  1276. X        ErrPerPixel = ((TotalErr / gdesc.gd_Height) * 1000) / gdesc.gd_Width;
  1277. X        MySPrintf(TextBuf, "%ld.%03ld", ErrPerPixel / 1000, ErrPerPixel % 1000);
  1278. X
  1279. X        MyPrintf("\x9B" "4DTotal colour error = %ld, Mean per line = %ld, Per pixel = %s.\n",
  1280. X            TotalErr, TotalErr / gdesc.gd_Height, TextBuf);
  1281. X    }
  1282. X}
  1283. END_OF_FILE
  1284. if test 5180 -ne `wc -c <'Sources/giftosham.c'`; then
  1285.     echo shar: \"'Sources/giftosham.c'\" unpacked with wrong size!
  1286. fi
  1287. # end of 'Sources/giftosham.c'
  1288. fi
  1289. if test -f 'Sources/largearrays.c' -a "${1}" != "-c" ; then 
  1290.   echo shar: Will not clobber existing file \"'Sources/largearrays.c'\"
  1291. else
  1292. echo shar: Extracting \"'Sources/largearrays.c'\" \(192 characters\)
  1293. sed "s/^X//" >'Sources/largearrays.c' <<'END_OF_FILE'
  1294. X/* Copyright 1990 by Christopher A. Wichura.
  1295. X   See file GIFMachine.doc for full description of rights.
  1296. X*/
  1297. X
  1298. X#include "GIFMachine.h"
  1299. X
  1300. XUBYTE PaletteBuf[MAXCOLOURS];
  1301. XULONG ColourBuf[MAXCOLOURS];
  1302. END_OF_FILE
  1303. if test 192 -ne `wc -c <'Sources/largearrays.c'`; then
  1304.     echo shar: \"'Sources/largearrays.c'\" unpacked with wrong size!
  1305. fi
  1306. # end of 'Sources/largearrays.c'
  1307. fi
  1308. if test -f 'Sources/lmkfile' -a "${1}" != "-c" ; then 
  1309.   echo shar: Will not clobber existing file \"'Sources/lmkfile'\"
  1310. else
  1311. echo shar: Extracting \"'Sources/lmkfile'\" \(1004 characters\)
  1312. sed "s/^X//" >'Sources/lmkfile' <<'END_OF_FILE'
  1313. X# lmkfile for GIFMachine
  1314. X# (c) 1990 by Christopher A. Wichura (caw@miroc.chi.il.us)
  1315. X
  1316. XCPU = -m0
  1317. XDEBUG = -d2
  1318. XCFLAGS = $(DEBUG) $(CPU) -v -cs -rr -fid -O
  1319. X
  1320. XND = NODEBUG
  1321. XLFLAGS = $(ND) SMALLCODE SMALLDATA
  1322. X
  1323. XHDR = GIFMachine.h
  1324. X
  1325. XOBJS = startup.o main.o mymem.o warncli.o doimage.o extensions.o writeiff.o 24to12.o stripborder.o xcomp.o doflip.o rgbdiff.o giftosham.o myprintf.o largearrays.o arg_help.o
  1326. XLIBS = LIB:LCR.lib LIB:debug.lib LIB:amiga2.0.lib
  1327. X
  1328. X.c.o:
  1329. X    LC $(CFLAGS) $*
  1330. X
  1331. X.a.o:
  1332. X    ASM -iINCLUDE: $*
  1333. X
  1334. X.txt.o:
  1335. X    TXTtoOBJ $*.txt $*.o _$* CODE
  1336. X
  1337. XGIFMachine: $(OBJS)
  1338. X    UpCVersion version.o
  1339. X    BLink <WITH < (GIFMachine.lnk)
  1340. XFROM $(OBJS) version.o
  1341. XTO GIFMachine
  1342. XLIB $(LIBS)
  1343. X$(LFLAGS)
  1344. X<
  1345. X
  1346. Xmain.o: main.c $(HDR)
  1347. X
  1348. Xdoimage.o: doimage.c $(HDR)
  1349. X
  1350. Xextensions.o: extensions.c $(HDR)
  1351. X
  1352. Xwriteiff.o: writeiff.c $(HDR)
  1353. X
  1354. Xstripborder.o: stripborder.c $(HDR)
  1355. X
  1356. Xxcomp.o: xcomp.c $(HDR)
  1357. X
  1358. Xdoflip.o: doflip.c $(HDR)
  1359. X
  1360. Xgiftosham.o: giftosham.c $(HDR)
  1361. X
  1362. Xrgbdiff.o: rgbdiff.c $(HDR)
  1363. X
  1364. X24to12.o: 24to12.c $(HDR)
  1365. X
  1366. Xlargearrays.o: largearrays.c $(HDR)
  1367. END_OF_FILE
  1368. if test 1004 -ne `wc -c <'Sources/lmkfile'`; then
  1369.     echo shar: \"'Sources/lmkfile'\" unpacked with wrong size!
  1370. fi
  1371. # end of 'Sources/lmkfile'
  1372. fi
  1373. if test -f 'Sources/mymem.c' -a "${1}" != "-c" ; then 
  1374.   echo shar: Will not clobber existing file \"'Sources/mymem.c'\"
  1375. else
  1376. echo shar: Extracting \"'Sources/mymem.c'\" \(1250 characters\)
  1377. sed "s/^X//" >'Sources/mymem.c' <<'END_OF_FILE'
  1378. X/* Copyright 1990 by Christopher A. Wichura.
  1379. X   See file GIFMachine.doc for full description of rights.
  1380. X*/
  1381. X
  1382. X#include <exec/types.h>
  1383. X#include <exec/lists.h>
  1384. X#include <exec/nodes.h>
  1385. X#include <exec/memory.h>
  1386. X#include <proto/exec.h>
  1387. X
  1388. Xstruct MyMem {
  1389. X    struct MinNode mm_Node;
  1390. X    ULONG mm_Size;
  1391. X};
  1392. X
  1393. Xstruct MinList Mem[2];
  1394. XUWORD CurrentMem;
  1395. X
  1396. Xvoid InitMemory(void)
  1397. X{
  1398. X    NewList((struct List *)&Mem[0]);
  1399. X    NewList((struct List *)&Mem[1]);
  1400. X    CurrentMem = 0;
  1401. X}
  1402. X
  1403. Xchar *MyAlloc(ULONG size)
  1404. X{
  1405. X    register struct MyMem *theMemory;
  1406. X    register ULONG newsize;
  1407. X
  1408. X    newsize = size + sizeof(struct MyMem);
  1409. X
  1410. X    if (!(theMemory = (struct MyMem *)AllocMem(newsize, MEMF_PUBLIC|MEMF_CLEAR)))
  1411. X        return NULL;
  1412. X
  1413. X    AddTail((struct List *)&Mem[CurrentMem], (struct Node *)&theMemory->mm_Node);
  1414. X    theMemory->mm_Size = newsize;
  1415. X
  1416. X    return (char *)theMemory + sizeof(struct MyMem);
  1417. X}
  1418. X
  1419. Xvoid MyFree(char *MemPtr)
  1420. X{
  1421. X    register struct MyMem *theMemory;
  1422. X
  1423. X    theMemory = (struct MyMem *)(MemPtr - sizeof(struct MyMem));
  1424. X
  1425. X    Remove((struct Node *)&theMemory->mm_Node);
  1426. X    FreeMem((char *)theMemory, theMemory->mm_Size);
  1427. X}
  1428. X
  1429. Xvoid FreeAll(UWORD memlist)
  1430. X{
  1431. X    register struct MyMem *theMemory;
  1432. X
  1433. X    while (theMemory = (struct MyMem *)RemTail((struct List *)&Mem[memlist]))
  1434. X        FreeMem((char *)theMemory, theMemory->mm_Size);
  1435. X}
  1436. END_OF_FILE
  1437. if test 1250 -ne `wc -c <'Sources/mymem.c'`; then
  1438.     echo shar: \"'Sources/mymem.c'\" unpacked with wrong size!
  1439. fi
  1440. # end of 'Sources/mymem.c'
  1441. fi
  1442. if test -f 'Sources/myprintf.c' -a "${1}" != "-c" ; then 
  1443.   echo shar: Will not clobber existing file \"'Sources/myprintf.c'\"
  1444. else
  1445. echo shar: Extracting \"'Sources/myprintf.c'\" \(712 characters\)
  1446. sed "s/^X//" >'Sources/myprintf.c' <<'END_OF_FILE'
  1447. X#include <proto/dos.h>
  1448. X#include <stdarg.h>
  1449. X
  1450. Xvoid RawDoFmt(char *, APTR, void(*)(), APTR);
  1451. X#pragma syscall RawDoFmt 20a ba9804
  1452. X
  1453. Xvoid __stdargs MyPrintf(char *fmt, ...)
  1454. X{
  1455. X    va_list args;
  1456. X
  1457. X    va_start(args, fmt);
  1458. X    VPrintf((UBYTE *)fmt, (LONG *)args);
  1459. X    Flush(Output());
  1460. X    va_end(args);
  1461. X}
  1462. X
  1463. Xstatic void __regargs MySPrintfSupp(char);
  1464. X
  1465. Xvoid __stdargs MySPrintf(char *buf, char *fmt, ...)
  1466. X{
  1467. X    va_list args;
  1468. X
  1469. X    va_start(args, fmt);
  1470. X    RawDoFmt(fmt, (APTR)args, MySPrintfSupp, (APTR)buf)
  1471. X    va_end(args);
  1472. X}
  1473. X
  1474. Xextern long __builtin_getreg(int);
  1475. Xextern void __builtin_putreg(int, char *);
  1476. X
  1477. Xstatic void __regargs MySPrintfSupp(char Char)
  1478. X{
  1479. X    char *ptr;
  1480. X
  1481. X    ptr = (char *)__builtin_getreg(11);
  1482. X    *ptr++ = Char;
  1483. X    __builtin_putreg(11, ptr);
  1484. X}
  1485. END_OF_FILE
  1486. if test 712 -ne `wc -c <'Sources/myprintf.c'`; then
  1487.     echo shar: \"'Sources/myprintf.c'\" unpacked with wrong size!
  1488. fi
  1489. # end of 'Sources/myprintf.c'
  1490. fi
  1491. if test -f 'Sources/rgbdiff.c' -a "${1}" != "-c" ; then 
  1492.   echo shar: Will not clobber existing file \"'Sources/rgbdiff.c'\"
  1493. else
  1494. echo shar: Extracting \"'Sources/rgbdiff.c'\" \(876 characters\)
  1495. sed "s/^X//" >'Sources/rgbdiff.c' <<'END_OF_FILE'
  1496. X/* Note:  this colour comparison routine was snitched from HamSharp.
  1497. X
  1498. X   This has the side effect of allowing one to compare colour errors gotten
  1499. X   with GIFMachine to those gotten with (S)HamSharp.
  1500. X*/
  1501. X
  1502. X#include "GIFMachine.h"
  1503. X
  1504. Xstatic UBYTE Diff[16][16];
  1505. Xstatic UBYTE Intensity[16][16][16];
  1506. X
  1507. Xextern struct Library *MathIeeeDoubBasBase;
  1508. X
  1509. Xvoid InitDiff(void)
  1510. X{
  1511. X    register int i;
  1512. X    register int j;
  1513. X    register int r;
  1514. X    register int g;
  1515. X    register int b;
  1516. X
  1517. X    for (i = 0; i < 16; i++)
  1518. X        for (j = 0; j < 16; j++)
  1519. X            Diff[i][j] = (i - j) * (i - j);
  1520. X
  1521. X    for (r = 0; r < 16; r++)
  1522. X        for (g = 0; g < 16; g++)
  1523. X            for (b = 0; b < 16; b++)
  1524. X                Intensity[r][g][b] = (int)(.299 * r + .587 * g + .114 * b);
  1525. X}
  1526. X
  1527. XULONG RGBdiff(UBYTE r1, UBYTE g1, UBYTE b1, UBYTE r2, UBYTE g2, UBYTE b2)
  1528. X{
  1529. X    return (ULONG)(Diff[Intensity[r1][g1][b1]][Intensity[r2][g2][b2]] +
  1530. X        Diff[r1][r2] + Diff[g1][g2] + Diff[b1][b2]);
  1531. X}
  1532. END_OF_FILE
  1533. if test 876 -ne `wc -c <'Sources/rgbdiff.c'`; then
  1534.     echo shar: \"'Sources/rgbdiff.c'\" unpacked with wrong size!
  1535. fi
  1536. # end of 'Sources/rgbdiff.c'
  1537. fi
  1538. if test -f 'Sources/startup.a' -a "${1}" != "-c" ; then 
  1539.   echo shar: Will not clobber existing file \"'Sources/startup.a'\"
  1540. else
  1541. echo shar: Extracting \"'Sources/startup.a'\" \(4359 characters\)
  1542. sed "s/^X//" >'Sources/startup.a' <<'END_OF_FILE'
  1543. X INCLUDE "exec/types.i"
  1544. X INCLUDE "exec/execbase.i"
  1545. X INCLUDE "exec/memory.i"
  1546. X INCLUDE "libraries/dosextens.i"
  1547. X
  1548. X XREF @main
  1549. X
  1550. X XREF _LVOOpenLibrary
  1551. X XREF _LVOOldOpenLibrary
  1552. X XREF _LVOCloseLibrary
  1553. X XREF _LVOSetSignal
  1554. X XREF _LVOForbid
  1555. X XREF _LVOWaitPort
  1556. X XREF _LVOGetMsg
  1557. X XREF _LVOReplyMsg
  1558. X XREF _LVOSetIoErr
  1559. X XREF _LVOAllocVec
  1560. X XREF _LVOFreeVec
  1561. X XREF _LVOOutput
  1562. X XREF _LVOWrite
  1563. X
  1564. X XREF _LinkerDB
  1565. X XREF __BSSBAS
  1566. X XREF __BSSLEN
  1567. X XREF _RESLEN
  1568. X XREF _RESBASE
  1569. X XREF _NEWDATAL
  1570. X
  1571. X XREF _AbsExecBase
  1572. X
  1573. XLIBCALL    MACRO
  1574. X    jsr _LVO\1(a6)
  1575. X    ENDM
  1576. X
  1577. X  SECTION StartCode,CODE
  1578. X
  1579. Xinit:
  1580. X    movem.l    d0/a0,-(sp)
  1581. X
  1582. X; first off we will check for our workbench message, if any.  we will store
  1583. X; the pointer to it in d7 temporarily until we actually copy the data
  1584. X; segment over.  otherwise we wouldn't be residentiable.
  1585. X
  1586. X    moveq    #0,d7        ; clear out longword
  1587. X
  1588. X; get address of our task
  1589. X    move.l    _AbsExecBase.W,a6
  1590. X    move.l    ThisTask(a6),a3
  1591. X
  1592. X; clear any pending signals
  1593. X    moveq    #0,d0
  1594. X    move.l    #$00003000,d1
  1595. X    LIBCALL    SetSignal
  1596. X
  1597. X; check for workbench message
  1598. X    tst.l    pr_CLI(a3)
  1599. X    bne.s    FromCLI
  1600. X
  1601. X    lea    pr_MsgPort(a3),a0
  1602. X    LIBCALL    WaitPort
  1603. X    lea    pr_MsgPort(a3),a0
  1604. X    LIBCALL    GetMsg
  1605. X    move.l    d0,d7
  1606. X
  1607. XFromCLI:
  1608. X    lea    DOSlib(pc),a1
  1609. X    moveq    #36,d0
  1610. X    LIBCALL    OpenLibrary
  1611. X    tst.l    d0
  1612. X    bne.s    DoMain
  1613. X
  1614. X    lea    DOSlib(pc),a1
  1615. X    LIBCALL    OldOpenLibrary
  1616. X    tst.l    d0
  1617. X    beq.s    bomb
  1618. X
  1619. X    move.l    d0,a6
  1620. X    LIBCALL    Output
  1621. X    move.l    d0,d1
  1622. X    beq.s    bomb
  1623. X
  1624. X    lea    Msg1(pc),a0
  1625. X    move.l    a0,d2
  1626. X    moveq    #Msg1Len,d3
  1627. X    LIBCALL    Write
  1628. X
  1629. X    move.l    a6,a1
  1630. X    move.l    _AbsExecBase.W,a6
  1631. X    LIBCALL    CloseLibrary
  1632. X
  1633. Xbomb:    addq.l    #8,sp        ; pop d0/a0 off stack
  1634. X
  1635. X    move.l    d7,d0        ; check if we have a workbench startup
  1636. X    bsr    ReplyWB        ; message and reply it if so
  1637. X
  1638. X    moveq    #0,d0
  1639. X    rts
  1640. X
  1641. XDoMain:
  1642. X    move.l    d0,-(sp)
  1643. X
  1644. X    lea    _LinkerDB,a4
  1645. X    sub.l    #_RESBASE,a4
  1646. X
  1647. X; get mem to hold data and bss stuff
  1648. X    move.l    #_RESLEN,d0
  1649. X    move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  1650. X    LIBCALL    AllocVec
  1651. X    tst.l    d0
  1652. X    bne.s    gotmem
  1653. X
  1654. X; no mem available so bomb out
  1655. X    move.l    d7,d0        ; check for wb startup message and reply
  1656. X    bsr    ReplyWB        ; it if present
  1657. X
  1658. X    move.l    (sp)+,a6    ; get dos base
  1659. X    addq.l    #8,sp        ; pop d0/a0 off of stack
  1660. X
  1661. X    moveq    #ERROR_NO_FREE_STORE,d1
  1662. X    LIBCALL    SetIoErr
  1663. X
  1664. X    move.l    a6,a1
  1665. X    move.l    _AbsExecBase.W,a6
  1666. X    LIBCALL    CloseLibrary
  1667. X
  1668. X    moveq    #20,d0
  1669. X    rts
  1670. X
  1671. X; get ready to copy data over into freshly alloced data area
  1672. Xgotmem:    move.l    d0,a0
  1673. X    move.l    d0,a2
  1674. X
  1675. X    move.l    d0,a1
  1676. X    move.l    #_NEWDATAL,d0
  1677. Xcpy:    move.l    (a4)+,(a0)+
  1678. X    subq.l    #1,d0
  1679. X    bne.s    cpy
  1680. X
  1681. X; now do the relocs for resident data
  1682. X    move.l    (a4)+,d0
  1683. Xreloc:    beq.s    nreloc
  1684. X    move.l    a1,a0
  1685. X    add.l    (a4)+,a0
  1686. X    add.l    (a0),a2
  1687. X    move.l    a2,(a0)
  1688. X    move.l    a1,a2
  1689. X    subq.l    #1,d0
  1690. X    bra.s    reloc
  1691. X
  1692. Xnreloc:    move.l    a1,a4
  1693. X    add.l    #_RESBASE,a4
  1694. X
  1695. X; stash some important junk away
  1696. X    move.l    (sp)+,_DOSBase(a4)
  1697. X    move.l    d7,_WBenchMsg(a4)
  1698. X
  1699. X    move.l    _AbsExecBase.W,a6
  1700. X    move.l    a6,_SysBase(a4)
  1701. X
  1702. X; call our main program.  we call the main routine with the following
  1703. X; arguments:
  1704. X;
  1705. X;   d0 = length of command line
  1706. X;   a0 = pointer to command line
  1707. X;   a1 = pointer to workbench startup message (or NULL)
  1708. X
  1709. X    movem.l    (sp)+,d0/a0
  1710. X    movem.l    sp,__StackPtr(a4)
  1711. X
  1712. X    movea.l    d7,a1
  1713. X    jsr    @main
  1714. X    moveq    #0,d0
  1715. X    bra.s    Exit
  1716. X
  1717. X XDEF _XCEXIT
  1718. X_XCEXIT:
  1719. X    move.l    4(sp),d0
  1720. X XDEF @XCEXIT
  1721. X@XCEXIT:
  1722. X
  1723. XExit:    move.l    d0,d3            ; save return code in safe place
  1724. X
  1725. X    move.l    _WBenchMsg(a4),d0    ; check if we need to reply the
  1726. X    bsr    ReplyWB            ; workbench startup message
  1727. X
  1728. X    move.l    _DOSBase(a4),a6
  1729. X    moveq    #0,d1
  1730. X    LIBCALL    SetIoErr
  1731. X
  1732. X    move.l    a6,a1
  1733. X    move.l    _AbsExecBase.W,a6
  1734. X    LIBCALL    CloseLibrary
  1735. X
  1736. X    movea.l    __StackPtr(a4),sp
  1737. X
  1738. X    move.l    a4,a1
  1739. X    sub.l    #_RESBASE,a1
  1740. X    LIBCALL    FreeVec
  1741. X
  1742. X    move.l    d3,d0            ; restore return code
  1743. X    rts
  1744. X
  1745. X; this subroutine is called when we try to check if we need to reply
  1746. X; the workbench message.  This is done because we do this in more than
  1747. X; one place.
  1748. X
  1749. XReplyWB:
  1750. X    move.l    d0,d2
  1751. X    beq.s    1$
  1752. X
  1753. X    move.l    _AbsExecBase.W,a6
  1754. X    LIBCALL    Forbid
  1755. X    movea.l    d2,a1
  1756. X    LIBCALL    ReplyMsg
  1757. X
  1758. X1$    rts
  1759. X
  1760. X; ---- This is the data we need for the startup module.  we don't put it in
  1761. X;      a data segment, though, or it would end up being copied over when we
  1762. X;      clone the data hunk and this stuff isn't needed anywhere else...
  1763. X
  1764. XDOSlib    dc.b "dos.library",0
  1765. X
  1766. XMsg1    dc.b "You need KickStart 2.0 or greater.",13
  1767. XMsg1Len    EQU *-Msg1
  1768. X    ds.w 0
  1769. X
  1770. X; ---- This is the BBS segment that holds various startup junk for us.
  1771. X
  1772. X   SECTION __MERGED,BSS
  1773. X
  1774. X XDEF _DOSBase
  1775. X XDEF _SysBase
  1776. X XDEF _IntuitionBase
  1777. X XDEF _WBenchMsg
  1778. X XDEF __StackPtr
  1779. X
  1780. X_DOSBase    ds.b 4
  1781. X_SysBase    ds.b 4
  1782. X_IntuitionBase    ds.b 4
  1783. X_WBenchMsg    ds.b 4
  1784. X__StackPtr    ds.b 4
  1785. X
  1786. X   END
  1787. END_OF_FILE
  1788. if test 4359 -ne `wc -c <'Sources/startup.a'`; then
  1789.     echo shar: \"'Sources/startup.a'\" unpacked with wrong size!
  1790. fi
  1791. # end of 'Sources/startup.a'
  1792. fi
  1793. if test -f 'Sources/stripborder.c' -a "${1}" != "-c" ; then 
  1794.   echo shar: Will not clobber existing file \"'Sources/stripborder.c'\"
  1795. else
  1796. echo shar: Extracting \"'Sources/stripborder.c'\" \(3390 characters\)
  1797. sed "s/^X//" >'Sources/stripborder.c' <<'END_OF_FILE'
  1798. X/* Copyright 1990 by Christopher A. Wichura.
  1799. X   See file GIFMachine.doc for full description of rights.
  1800. X*/
  1801. X
  1802. X#include "GIFMachine.h"
  1803. X
  1804. Xextern struct GIFdescriptor gdesc;
  1805. XEXTERNBITPLANE;
  1806. X
  1807. Xextern char *AbortMsg;
  1808. X
  1809. Xextern int NoBorderLineThresh;
  1810. X
  1811. X#define BorderCheck(a, b) ((BitPlane[b][a].rgb_Red   != BorderCol.rgb_Red) || \
  1812. X               (BitPlane[b][a].rgb_Green != BorderCol.rgb_Green) || \
  1813. X               (BitPlane[b][a].rgb_Blue  != BorderCol.rgb_Blue))
  1814. X
  1815. Xvoid StripBorder(void)
  1816. X{
  1817. X    register UWORD x;
  1818. X    register UWORD y;
  1819. X    register int thresh;
  1820. X    register BOOL breakout;
  1821. X    LONG LeftEdge, TopEdge;
  1822. X    LONG Width, Height;
  1823. X    UWORD OrigWidth, OrigHeight;
  1824. X    int WidthThresh, HeightThresh;
  1825. X    int Corner;
  1826. X
  1827. X    struct RGB BorderCol;
  1828. X
  1829. X    PutStr("...Removing border.\n");
  1830. X
  1831. X    OrigWidth = gdesc.gd_Width;
  1832. X    OrigHeight = gdesc.gd_Height;
  1833. X
  1834. X    for (Corner = 0; Corner < 4; Corner++) {
  1835. X        x = (Corner & 1) ? (gdesc.gd_Width - 1) : 0;
  1836. X        y = (Corner & 2) ? (gdesc.gd_Height - 1) : 0;
  1837. X
  1838. X        BorderCol = BitPlane[y][x];
  1839. X
  1840. X        WidthThresh  = NoBorderLineThresh * gdesc.gd_Width  / 100;
  1841. X        HeightThresh = NoBorderLineThresh * gdesc.gd_Height / 100;
  1842. X
  1843. X        for (breakout = y = 0; (y < gdesc.gd_Height) && !breakout; y++) {
  1844. X            for (thresh = x = 0; x < gdesc.gd_Width; x++)
  1845. X                if (BorderCheck(x, y))
  1846. X                    if (++thresh > WidthThresh) {
  1847. X                        breakout = TRUE;
  1848. X                        break;
  1849. X                    }
  1850. X
  1851. X            if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  1852. X                PutStr(AbortMsg);
  1853. X                MyExit(ABORTEXITVAL);
  1854. X            }
  1855. X        }
  1856. X
  1857. X        TopEdge = y - 1;
  1858. X
  1859. X        for (breakout = 0, y = gdesc.gd_Height - 1; (y > 0) && !breakout; y--) {
  1860. X            for (thresh = x = 0; x < gdesc.gd_Width; x++)
  1861. X                if (BorderCheck(x, y))
  1862. X                    if (++thresh > WidthThresh) {
  1863. X                        breakout = TRUE;
  1864. X                        break;
  1865. X                    }
  1866. X
  1867. X            if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  1868. X                PutStr(AbortMsg);
  1869. X                MyExit(ABORTEXITVAL);
  1870. X            }
  1871. X        }
  1872. X
  1873. X        Height = y - TopEdge + 2;
  1874. X
  1875. X        for (breakout = x = 0; (x < gdesc.gd_Width) && !breakout; x++) {
  1876. X            for (thresh = y = 0; y < gdesc.gd_Height; y++)
  1877. X                if (BorderCheck(x, y))
  1878. X                    if (++thresh > HeightThresh) {
  1879. X                        breakout = TRUE;
  1880. X                        break;
  1881. X                    }
  1882. X
  1883. X            if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  1884. X                PutStr(AbortMsg);
  1885. X                MyExit(ABORTEXITVAL);
  1886. X            }
  1887. X        }
  1888. X
  1889. X        LeftEdge = x - 1;
  1890. X
  1891. X        for (breakout = 0, x = gdesc.gd_Width - 1; (x > 0) && !breakout; x--) {
  1892. X            for (thresh = y = 0; y < gdesc.gd_Height; y++)
  1893. X                if (BorderCheck(x, y))
  1894. X                    if (++thresh > HeightThresh) {
  1895. X                        breakout = TRUE;
  1896. X                        break;
  1897. X                    }
  1898. X
  1899. X            if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  1900. X                PutStr(AbortMsg);
  1901. X                MyExit(ABORTEXITVAL);
  1902. X            }
  1903. X        }
  1904. X
  1905. X        Width = x - LeftEdge + 2;
  1906. X
  1907. X        if ((Width != gdesc.gd_Width) || (Height != gdesc.gd_Height)) {
  1908. X            if (Width < 5 || Height < 5) {
  1909. X                PutStr("......Too much of picture would be removed.  Not modified.\n");
  1910. X                return;
  1911. X            }
  1912. X
  1913. X            for (y = 0; y < Height; y++) {
  1914. X                for (x = 0; x < Width; x++)
  1915. X                    BitPlane[y][x] = BitPlane[TopEdge + y][LeftEdge + x];
  1916. X
  1917. X                BitPlane[y][x].rgb_Red   =
  1918. X                BitPlane[y][x].rgb_Green =
  1919. X                BitPlane[y][x].rgb_Blue  = 0;
  1920. X
  1921. X                if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  1922. X                    PutStr(AbortMsg);
  1923. X                    MyExit(ABORTEXITVAL);
  1924. X                }
  1925. X            }
  1926. X
  1927. X            gdesc.gd_Width = Width;
  1928. X            gdesc.gd_Height = Height;
  1929. X        }
  1930. X    }
  1931. X
  1932. X    if ((gdesc.gd_Width != OrigWidth) || (gdesc.gd_Height != OrigHeight)) {
  1933. X        if (gdesc.gd_Width & 1)
  1934. X            gdesc.gd_Width++;
  1935. X
  1936. X        MyPrintf("......New width = %ld, New height = %ld\n",
  1937. X            gdesc.gd_Width, gdesc.gd_Height);
  1938. X    }
  1939. X}
  1940. END_OF_FILE
  1941. if test 3390 -ne `wc -c <'Sources/stripborder.c'`; then
  1942.     echo shar: \"'Sources/stripborder.c'\" unpacked with wrong size!
  1943. fi
  1944. # end of 'Sources/stripborder.c'
  1945. fi
  1946. if test -f 'Sources/version.o.uu' -a "${1}" != "-c" ; then 
  1947.   echo shar: Will not clobber existing file \"'Sources/version.o.uu'\"
  1948. else
  1949. echo shar: Extracting \"'Sources/version.o.uu'\" \(197 characters\)
  1950. sed "s/^X//" >'Sources/version.o.uu' <<'END_OF_FILE'
  1951. Xbegin 666 version.o
  1952. XM```#YP````````/I````!P````(```!T,BXQ,38@*#$U($9E8B`Y,2D`````9
  1953. XM``/O`0```E]697)S:6]N``````$```-?5F5R<VEO;DE$```````(`0```U]2-
  1954. X6979I<VEO;@````````0````````#\@-?8
  1955. X``
  1956. Xend
  1957. Xsize 112
  1958. END_OF_FILE
  1959. if test 197 -ne `wc -c <'Sources/version.o.uu'`; then
  1960.     echo shar: \"'Sources/version.o.uu'\" unpacked with wrong size!
  1961. fi
  1962. # end of 'Sources/version.o.uu'
  1963. fi
  1964. if test -f 'Sources/warncli.c' -a "${1}" != "-c" ; then 
  1965.   echo shar: Will not clobber existing file \"'Sources/warncli.c'\"
  1966. else
  1967. echo shar: Extracting \"'Sources/warncli.c'\" \(1701 characters\)
  1968. sed "s/^X//" >'Sources/warncli.c' <<'END_OF_FILE'
  1969. X/* Copyright 1990 by Christopher A. Wichura.
  1970. X   See file GIFMachine.doc for full description of rights.
  1971. X*/
  1972. X
  1973. X#include <exec/types.h>
  1974. X#include <intuition/intuition.h>
  1975. X#include <graphics/text.h>
  1976. X#include <proto/exec.h>
  1977. X#include <proto/intuition.h>
  1978. X
  1979. Xstatic struct TextAttr TOPAZ60 = {"topaz.font", TOPAZ_SIXTY,
  1980. X    FS_NORMAL, FPF_ROMFONT};
  1981. X
  1982. Xstatic struct IntuiText BodyText2 = {-1, -1,    /* pen numbers */
  1983. X                             0,             /* draw mode */
  1984. X                             9,14,          /* starting offsets */
  1985. X                             &TOPAZ60,      /* text attribute pointer */
  1986. X                             "for CLI use only!",
  1987. X                             NULL };
  1988. X
  1989. Xstatic struct IntuiText BodyText1 = {-1,-1,      /* pen numbers */
  1990. X                             0,             /* draw mode */
  1991. X                             29,4,          /* starting offsets */
  1992. X                             &TOPAZ60,      /* text attribute pointer */
  1993. X                             "GIFMachine is",
  1994. X                             &BodyText2 };
  1995. X
  1996. Xstatic struct IntuiText ContinueText = {-1,-1,  /* pen numbers */
  1997. X                             0,             /* draw mode */
  1998. X                             4,4,           /* starting offsets */
  1999. X                             &TOPAZ60,      /* text attribute pointer */
  2000. X                             "CONTINUE",
  2001. X                             NULL };
  2002. X
  2003. Xvoid WarnMustUseCLI(void)
  2004. X{
  2005. X    BOOL    OpenedIntui;
  2006. X
  2007. X    if (IntuitionBase)
  2008. X        OpenedIntui = FALSE;
  2009. X    else {
  2010. X        if (!(IntuitionBase = OpenLibrary("intuition.library", 0)))
  2011. X            return;
  2012. X        OpenedIntui = TRUE;
  2013. X    }
  2014. X
  2015. X    AutoRequest(NULL,&BodyText1,NULL,&ContinueText,0,0,220,64);
  2016. X
  2017. X    if (OpenedIntui)
  2018. X        CloseLibrary(IntuitionBase);
  2019. X}
  2020. END_OF_FILE
  2021. if test 1701 -ne `wc -c <'Sources/warncli.c'`; then
  2022.     echo shar: \"'Sources/warncli.c'\" unpacked with wrong size!
  2023. fi
  2024. # end of 'Sources/warncli.c'
  2025. fi
  2026. if test -f 'Sources/writeiff.c' -a "${1}" != "-c" ; then 
  2027.   echo shar: Will not clobber existing file \"'Sources/writeiff.c'\"
  2028. else
  2029. echo shar: Extracting \"'Sources/writeiff.c'\" \(9577 characters\)
  2030. sed "s/^X//" >'Sources/writeiff.c' <<'END_OF_FILE'
  2031. X/* Copyright 1990 by Christopher A. Wichura.
  2032. X   See file GIFMachine.doc for full description of rights.
  2033. X*/
  2034. X
  2035. X#include "GIFMachine.h"
  2036. X#include <iff/ILBM.h>
  2037. X#include <libraries/iffparse.h>
  2038. X#include <graphics/view.h>
  2039. X#include <proto/iffparse.h>
  2040. X#include <dos/datetime.h>
  2041. X
  2042. Xextern struct GIFdescriptor gdesc;
  2043. XEXTERNBITPLANE;
  2044. X
  2045. Xextern struct MinList CommentList;
  2046. X
  2047. Xextern char *AbortMsg;
  2048. X
  2049. Xextern UWORD *SHAMmem;
  2050. XBYTE *PlaneBuf;
  2051. X
  2052. XBOOL Laced;
  2053. X
  2054. XUBYTE *Planes[24];
  2055. X
  2056. Xstatic UBYTE CompBuf[256];
  2057. Xstatic ULONG PlanePos;
  2058. X
  2059. X/* our version number stuff */
  2060. Xextern ULONG __far Version;
  2061. Xextern ULONG __far Revision;
  2062. X
  2063. XBOOL WriteIFF(char *tofile, BOOL DeepFlag)
  2064. X{
  2065. X    register struct IFFHandle *iff;
  2066. X    register int index;
  2067. X    register ULONG ChunkSize;
  2068. X    register UWORD current;
  2069. X    char WrittenBy[40];
  2070. X
  2071. X    ColorRegister ColourBuf;
  2072. X    BitMapHeader  bmh;
  2073. X
  2074. X    PutStr("...Writing IFF file.");
  2075. X
  2076. X    if (!(iff = AllocIFF())) {
  2077. X        PutStr("\n......Error allocating IFF handle.\n");
  2078. X        return TRUE;
  2079. X    }
  2080. X
  2081. X    if (!(iff->iff_Stream = Open(tofile, MODE_NEWFILE))) {
  2082. X        MyPrintf("\n......Error %ld trying to create %s.", IoErr(), tofile);
  2083. X        goto EndWriteIFF;
  2084. X    }
  2085. X
  2086. X    InitIFFasDOS(iff);
  2087. X
  2088. X    if (OpenIFF(iff, IFFF_WRITE)) {
  2089. X        PutStr("\n......Error writing to IFF.\n");
  2090. X        goto EndWriteIFF;
  2091. X    }
  2092. X
  2093. X    if (PushChunk(iff, ID_ILBM, FORM, IFFSIZE_UNKNOWN)) {
  2094. X        PutStr("\n......Error writing to IFF.\n");
  2095. X        goto EndWriteIFF;
  2096. X    }
  2097. X
  2098. X    if (PushChunk(iff, 0L, MakeID('A','N','N','O'), IFFSIZE_UNKNOWN)) {
  2099. X        PutStr("\n......Error writing to IFF.\n");
  2100. X        goto EndWriteIFF;
  2101. X    }
  2102. X
  2103. X    MySPrintf(WrittenBy, "Written by GIFMachine v%ld.%ld on ", Version, Revision);
  2104. X
  2105. X    if (WriteChunkBytes(iff, (APTR)&WrittenBy, strlen(WrittenBy)) != strlen(WrittenBy)) {
  2106. X        PutStr("\n......Error writing to IFF.\n");
  2107. X        goto EndWriteIFF;
  2108. X    }
  2109. X
  2110. X    {
  2111. X        struct DateTime dat;
  2112. X        char Date[LEN_DATSTRING + 1];
  2113. X        int DateLength;
  2114. X
  2115. X        DateStamp(&dat.dat_Stamp);
  2116. X        dat.dat_Format = FORMAT_DOS;
  2117. X        dat.dat_Flags = 0;
  2118. X        dat.dat_StrDay = NULL;
  2119. X        dat.dat_StrDate = Date;
  2120. X        dat.dat_StrTime = NULL;
  2121. X
  2122. X        memset(Date, 0, LEN_DATSTRING + 1);
  2123. X        DateToStr(&dat);
  2124. X
  2125. X        DateLength = strlen(Date) + 1;
  2126. X        if (WriteChunkBytes(iff, (APTR)&Date, DateLength) != DateLength) {
  2127. X            PutStr("\n......Error writing to IFF.\n");
  2128. X            goto EndWriteIFF;
  2129. X        }
  2130. X    }
  2131. X
  2132. X    if (PopChunk(iff)) {
  2133. X        PutStr("\n......Error writing to IFF.\n");
  2134. X        goto EndWriteIFF;
  2135. X    }
  2136. X
  2137. X    {
  2138. X        struct CommentNode *cn;
  2139. X        char ANNObuf[1];
  2140. X
  2141. X#define C_BLOCK_ID "GIF Comment Block: "
  2142. X
  2143. X        ANNObuf[0] = 0;
  2144. X
  2145. X        while (cn = (struct CommentNode *)RemHead((struct List *)&CommentList)) {
  2146. X            if (PushChunk(iff, 0L, MakeID('A','N','N','O'), IFFSIZE_UNKNOWN)) {
  2147. X                PutStr("\n......Error writing to IFF.\n");
  2148. X                goto EndWriteIFF;
  2149. X            }
  2150. X
  2151. X            if (WriteChunkBytes(iff, (APTR)C_BLOCK_ID, strlen(C_BLOCK_ID)) != strlen(C_BLOCK_ID)) {
  2152. X                PutStr("\n......Error writing to IFF.\n");
  2153. X                goto EndWriteIFF;
  2154. X            }
  2155. X
  2156. X            if (WriteChunkBytes(iff, (APTR)cn->cn_Comment, cn->cn_CommentLength) != cn->cn_CommentLength) {
  2157. X                PutStr("\n......Error writing to IFF.\n");
  2158. X                goto EndWriteIFF;
  2159. X            }
  2160. X
  2161. X            if (WriteChunkBytes(iff, (APTR)ANNObuf, 1) != 1) {
  2162. X                PutStr("\n......Error writing to IFF.\n");
  2163. X                goto EndWriteIFF;
  2164. X            }
  2165. X
  2166. X            if (PopChunk(iff)) {
  2167. X                PutStr("\n......Error writing to IFF.\n");
  2168. X                goto EndWriteIFF;
  2169. X            }
  2170. X        }
  2171. X    }
  2172. X
  2173. X    if (PushChunk(iff, 0L, ID_BMHD, sizeof(BitMapHeader))) {
  2174. X        PutStr("\n......Error writing to IFF.\n");
  2175. X        goto EndWriteIFF;
  2176. X    }
  2177. X
  2178. X    bmh.w                 = (gdesc.gd_Width & 1) ? gdesc.gd_Width + 1 : gdesc.gd_Width;
  2179. X    bmh.h                 = (gdesc.gd_Height & 1) ? gdesc.gd_Height + 1 : gdesc.gd_Height;
  2180. X    bmh.x       = bmh.y  = 0;
  2181. X    bmh.nPlanes          = (DeepFlag ? 24 : 6);
  2182. X    bmh.masking          = mskNone;
  2183. X    bmh.compression      = cmpByteRun1;
  2184. X    bmh.pad1             = 0;
  2185. X    bmh.transparentColor = 0;
  2186. X    bmh.xAspect          = (Laced ? x320x400Aspect : x320x200Aspect);
  2187. X    bmh.yAspect          = (Laced ? y320x400Aspect : y320x200Aspect);
  2188. X    bmh.pageWidth        = 320;
  2189. X    bmh.pageHeight       = (Laced ? 400 : 200);
  2190. X
  2191. X    if (WriteChunkBytes(iff, (APTR)&bmh, sizeof(BitMapHeader)) != sizeof(BitMapHeader)) {
  2192. X        PutStr("\n......Error writing to IFF.\n");
  2193. X        goto EndWriteIFF;
  2194. X    }
  2195. X
  2196. X    if (PopChunk(iff)) {
  2197. X        PutStr("\n......Error writing to IFF.\n");
  2198. X        goto EndWriteIFF;
  2199. X    }
  2200. X
  2201. X    if (PushChunk(iff, 0L, ID_CAMG, 4)) {
  2202. X        PutStr("\n......Error writing to IFF.\n");
  2203. X        goto EndWriteIFF;
  2204. X    }
  2205. X
  2206. X    {
  2207. X        LONG CAMGbuf[1];
  2208. X
  2209. X        CAMGbuf[0] = (DeepFlag ? 0 : HAM) | (Laced ? LACE : 0);
  2210. X
  2211. X        if (WriteChunkBytes(iff, (APTR)&CAMGbuf, 4) != 4) {
  2212. X            PutStr("\n......Error writing to IFF.\n");
  2213. X            goto EndWriteIFF;
  2214. X        }
  2215. X    }
  2216. X
  2217. X    if (PopChunk(iff)) {
  2218. X        PutStr("\n......Error writing to IFF.\n");
  2219. X        goto EndWriteIFF;
  2220. X    }
  2221. X
  2222. X    if (!DeepFlag) {
  2223. X        if (PushChunk(iff, 0L, ID_CMAP, 16 * 3)) {
  2224. X            PutStr("\n......Error writing to IFF.\n");
  2225. X            goto EndWriteIFF;
  2226. X        }
  2227. X
  2228. X        for (index = 0; index < 16; index++) {
  2229. X            current = SHAMmem[index];
  2230. X
  2231. X            ColourBuf.red   = (current >> 4) & 0xF0;
  2232. X            ColourBuf.green = current & 0xF0;
  2233. X            ColourBuf.blue  = (current & 15) << 4;
  2234. X
  2235. X            if (WriteChunkBytes(iff, (APTR)&ColourBuf, sizeofColorRegister) != sizeofColorRegister) {
  2236. X                PutStr("\n......Error writing to IFF.\n");
  2237. X                goto EndWriteIFF;
  2238. X            }
  2239. X        }
  2240. X
  2241. X        if (PopChunk(iff)) {
  2242. X            PutStr("\n......Error writing to IFF.\n");
  2243. X            goto EndWriteIFF;
  2244. X        }
  2245. X
  2246. X        ChunkSize = (Laced ? gdesc.gd_Height / 2 : gdesc.gd_Height) * 16 * sizeof(UWORD);
  2247. X
  2248. X        if (PushChunk(iff, 0L, MakeID('S','H','A','M'), IFFSIZE_UNKNOWN)) {
  2249. X            PutStr("\n......Error writing to IFF.\n");
  2250. X            goto EndWriteIFF;
  2251. X        }
  2252. X
  2253. X        {
  2254. X            UWORD SHAMversion[1];
  2255. X
  2256. X            SHAMversion[0] = 0;
  2257. X
  2258. X            if (WriteChunkBytes(iff, (APTR)&SHAMversion, sizeof(UWORD)) != sizeof(UWORD)) {
  2259. X                PutStr("\n......Error writing to IFF.\n");
  2260. X                goto EndWriteIFF;
  2261. X            }
  2262. X        }
  2263. X
  2264. X        if (WriteChunkBytes(iff, (APTR)SHAMmem, ChunkSize) != ChunkSize) {
  2265. X            PutStr("\n......Error writing to IFF.\n");
  2266. X            goto EndWriteIFF;
  2267. X        }
  2268. X
  2269. X        if (gdesc.gd_Height & 1) {
  2270. X            UWORD BlankSHAM[16];
  2271. X
  2272. X            memset((char *)BlankSHAM, 0, sizeof(BlankSHAM));
  2273. X
  2274. X            if (WriteChunkBytes(iff, (APTR)BlankSHAM, sizeof(BlankSHAM)) != sizeof(BlankSHAM)) {
  2275. X                PutStr("\n......Error writing to IFF.\n");
  2276. X                goto EndWriteIFF;
  2277. X            }
  2278. X        }
  2279. X
  2280. X        if (PopChunk(iff)) {
  2281. X            PutStr("\n......Error writing to IFF.\n");
  2282. X            goto EndWriteIFF;
  2283. X        }
  2284. X    } /* end if (!DeepFlag) */
  2285. X
  2286. X    if (PushChunk(iff, 0L, ID_BODY, IFFSIZE_UNKNOWN)) {
  2287. X        PutStr("\n......Error writing to IFF.\n");
  2288. X        goto EndWriteIFF;
  2289. X    }
  2290. X
  2291. X    /* now we actually write the body chunk out */
  2292. X    {
  2293. X        register int plane;
  2294. X        register int col;
  2295. X        register UWORD x;
  2296. X        register UWORD y;
  2297. X        register int index;
  2298. X        UBYTE PlaneMask, ColMask;
  2299. X        UWORD Cols;
  2300. X
  2301. X        PutStr("\n......Line ");
  2302. X
  2303. X        Cols = (bmh.w + 7) / 8;
  2304. X        if (IS_ODD(Cols))
  2305. X            Cols++;
  2306. X
  2307. X        for (y = 0; y < ((gdesc.gd_Height & 1) ? gdesc.gd_Height + 1 : gdesc.gd_Height) ; y++) {
  2308. X            MyPrintf("%5ld", y);
  2309. X
  2310. X            if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  2311. X                MyPrintf("\n%s", AbortMsg);
  2312. X                CloseIFF(iff);
  2313. X                Close(iff->iff_Stream);
  2314. X                FreeIFF(iff);
  2315. X                MyExit(ABORTEXITVAL);
  2316. X            }
  2317. X
  2318. X            if (y != gdesc.gd_Height)
  2319. X                for (index = 0; index < (DeepFlag ? 3 : 1); index++) {
  2320. X                    col = 0;
  2321. X                    ColMask = 1L << 7;
  2322. X
  2323. X                    for (x = 0; x < gdesc.gd_Width; x++) {
  2324. X                        if (DeepFlag)
  2325. X                            current = *((UBYTE *)&BitPlane[y][x]+index);
  2326. X                        else
  2327. X                            current = GetValue(x, y);
  2328. X
  2329. X                        PlaneMask = 1;
  2330. X                        for (plane = 0; plane < (DeepFlag ? 8 : 6); plane++) {
  2331. X                            if (current & PlaneMask)
  2332. X                                Planes[plane + index * 8][col] |= ColMask;
  2333. X
  2334. X                            PlaneMask <<= 1;
  2335. X                        }
  2336. X
  2337. X                        if (ColMask == 1) {
  2338. X                            ColMask = 1L << 7;
  2339. X                            col++;
  2340. X                        } else
  2341. X                            ColMask >>= 1;
  2342. X                    }
  2343. X                }
  2344. X
  2345. X            /* now we need to compress the scan line */
  2346. X
  2347. X            {
  2348. X                register BOOL state;
  2349. X                register char c;
  2350. X                register char lastc;
  2351. X                register UWORD nbuf;
  2352. X                register UWORD rstart;
  2353. X
  2354. X                for (plane = 0; plane < (DeepFlag ? 24 : 6); plane++) {
  2355. X
  2356. X                    CompBuf[0] = lastc = c = Planes[plane][0];
  2357. X
  2358. X                    state = FALSE;
  2359. X                    PlanePos = rstart = 0;
  2360. X                    nbuf = col = 1;
  2361. X
  2362. X                    while (col < Cols) {
  2363. X                        CompBuf[nbuf++] = c = Planes[plane][col++];
  2364. X
  2365. X                        switch (state) {
  2366. X                            case FALSE:
  2367. X                            if (nbuf > 128) {
  2368. X                                OutDump(nbuf - 1);
  2369. X                                CompBuf[0] = c;
  2370. X                                nbuf = 1;
  2371. X                                rstart = 0;
  2372. X                                break;
  2373. X                            }
  2374. X
  2375. X                            if (c == lastc) {
  2376. X                                if (nbuf - rstart >= 3) {
  2377. X                                    if (rstart > 0)
  2378. X                                            OutDump(rstart);
  2379. X                                    state = TRUE;
  2380. X                                } else if (rstart == 0)
  2381. X                                    state = TRUE;
  2382. X                            } else
  2383. X                                rstart = nbuf - 1;
  2384. X
  2385. X                            break;
  2386. X
  2387. X                            case TRUE:
  2388. X                            if ((c != lastc) || (nbuf - rstart > 128)) {
  2389. X                                OutRun(nbuf - 1 - rstart, lastc);
  2390. X                                CompBuf[0] = c;
  2391. X                                nbuf = 1;
  2392. X                                rstart = 0;
  2393. X                                state = FALSE;
  2394. X                            }
  2395. X
  2396. X                            break;
  2397. X                        }
  2398. X
  2399. X                        lastc = c;
  2400. X                    }
  2401. X
  2402. X                    switch (state) {
  2403. X                        case FALSE:
  2404. X                        OutDump(nbuf);
  2405. X                        break;
  2406. X
  2407. X                        case TRUE:
  2408. X                        OutRun(nbuf - rstart, lastc);
  2409. X                        break;
  2410. X                    }
  2411. X
  2412. X                    /* now write the compressed plane out */
  2413. X                    if (WriteChunkBytes(iff, (APTR)PlaneBuf, PlanePos) != PlanePos) {
  2414. X                        PutStr("\n......Error writing to IFF.\n");
  2415. X                        goto EndWriteIFF;
  2416. X                    }
  2417. X
  2418. X                    memset((char *)Planes[plane], 0, Cols);
  2419. X                }
  2420. X            }
  2421. X
  2422. X            MyPrintf("\x9B" "5D");
  2423. X        }
  2424. X
  2425. X    }
  2426. X
  2427. X    if (PopChunk(iff)) {
  2428. X        PutStr("\n......Error writing to IFF.\n");
  2429. X        goto EndWriteIFF;
  2430. X    }
  2431. X
  2432. X    if (PopChunk(iff)) {
  2433. X        PutStr("\n......Error writing to IFF.\n");
  2434. X        goto EndWriteIFF;
  2435. X    }
  2436. X
  2437. X    PutStr("\x9B" "5D\x9BKWritten.\n");
  2438. X
  2439. XEndWriteIFF:
  2440. X    CloseIFF(iff);
  2441. X    if (iff->iff_Stream)
  2442. X        Close(iff->iff_Stream);
  2443. X    FreeIFF(iff);
  2444. X
  2445. X    return TRUE;
  2446. X}
  2447. X
  2448. Xvoid OutDump(int nn)
  2449. X{
  2450. X    register int index;
  2451. X
  2452. X    PlaneBuf[PlanePos++] = nn - 1;
  2453. X
  2454. X    for (index = 0; index < nn; index++)
  2455. X        PlaneBuf[PlanePos++] = CompBuf[index];
  2456. X}
  2457. X
  2458. Xvoid OutRun(int nn, int cc)
  2459. X{
  2460. X    PlaneBuf[PlanePos++] = -(nn - 1);
  2461. X    PlaneBuf[PlanePos++] = cc;
  2462. X}
  2463. END_OF_FILE
  2464. if test 9577 -ne `wc -c <'Sources/writeiff.c'`; then
  2465.     echo shar: \"'Sources/writeiff.c'\" unpacked with wrong size!
  2466. fi
  2467. # end of 'Sources/writeiff.c'
  2468. fi
  2469. if test -f 'Sources/xcomp.c' -a "${1}" != "-c" ; then 
  2470.   echo shar: Will not clobber existing file \"'Sources/xcomp.c'\"
  2471. else
  2472. echo shar: Extracting \"'Sources/xcomp.c'\" \(2146 characters\)
  2473. sed "s/^X//" >'Sources/xcomp.c' <<'END_OF_FILE'
  2474. X/* Copyright 1990 by Christopher A. Wichura.
  2475. X   See file GIFMachine.doc for full description of rights.
  2476. X*/
  2477. X
  2478. X/* This function will take the gif screen we have read in and scale it to
  2479. X   one half of its previous X size.
  2480. X
  2481. X   What we do here is just a step above skipping every other pixel (like
  2482. X   most routines I have seen do).  While we still put emphasis on the
  2483. X   even pixels, we at least take account of the odds next to them by
  2484. X   using a weighted average.
  2485. X
  2486. X   This method is by no means the best way to do this.  If anyone wants
  2487. X   to build a smarter one I would be very interested in seeing it.
  2488. X*/
  2489. X
  2490. X#include "GIFMachine.h"
  2491. X
  2492. Xextern struct GIFdescriptor gdesc;
  2493. XEXTERNBITPLANE;
  2494. X
  2495. Xextern char *AbortMsg;
  2496. X
  2497. Xvoid DoXComp(void)
  2498. X{
  2499. X    register UWORD x1;
  2500. X    register UWORD x2;
  2501. X    register UWORD y;
  2502. X    register UWORD num;
  2503. X    UWORD ColBuf[3];
  2504. X    UWORD NewWidth;
  2505. X
  2506. X    NewWidth = gdesc.gd_Width >> 1;
  2507. X    if (NewWidth & 1)
  2508. X        NewWidth++;
  2509. X
  2510. X    MyPrintf("...Compressing width to %ld.\n......Line ", NewWidth);
  2511. X
  2512. X        for (y = 0; y < gdesc.gd_Height; y++) {
  2513. X        MyPrintf("%5ld", y);
  2514. X
  2515. X        for (x1 = x2 = 0; x2 < gdesc.gd_Width; x1++, x2 += 2) {
  2516. X            num = 4;
  2517. X
  2518. X            ColBuf[0] = BitPlane[y][x2].rgb_Red * 4;
  2519. X            ColBuf[1] = BitPlane[y][x2].rgb_Green * 4;
  2520. X            ColBuf[2] = BitPlane[y][x2].rgb_Blue * 4;
  2521. X
  2522. X            if (x2 > 1) {
  2523. X                num += 2;
  2524. X
  2525. X                ColBuf[0] += BitPlane[y][x2 - 1].rgb_Red * 2;
  2526. X                ColBuf[1] += BitPlane[y][x2 - 1].rgb_Green * 2;
  2527. X                ColBuf[2] += BitPlane[y][x2 - 1].rgb_Blue * 2;
  2528. X            }
  2529. X
  2530. X            if (x2 + 1 < gdesc.gd_Width) {
  2531. X                num += 2;
  2532. X
  2533. X                ColBuf[0] += BitPlane[y][x2 + 1].rgb_Red * 2;
  2534. X                ColBuf[1] += BitPlane[y][x2 + 1].rgb_Green * 2;
  2535. X                ColBuf[2] += BitPlane[y][x2 + 1].rgb_Blue * 2;
  2536. X            }
  2537. X
  2538. X            BitPlane[y][x1].rgb_Red   = ((ColBuf[0] + num / 2) / num);
  2539. X            BitPlane[y][x1].rgb_Green = ((ColBuf[1] + num / 2) / num);
  2540. X            BitPlane[y][x1].rgb_Blue  = ((ColBuf[2] + num / 2) / num);
  2541. X        }
  2542. X
  2543. X        BitPlane[y][x1].rgb_Red = BitPlane[y][x1].rgb_Green = BitPlane[y][x1].rgb_Blue = 0;
  2544. X
  2545. X        if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  2546. X            MyPrintf("\n%s", AbortMsg);
  2547. X            MyExit(ABORTEXITVAL);
  2548. X        }
  2549. X
  2550. X        PutStr("\x9B" "5D");
  2551. X    }
  2552. X
  2553. X    PutStr("\x9B" "5DCompressed.\n");
  2554. X
  2555. X    gdesc.gd_Width = NewWidth;
  2556. X}
  2557. END_OF_FILE
  2558. if test 2146 -ne `wc -c <'Sources/xcomp.c'`; then
  2559.     echo shar: \"'Sources/xcomp.c'\" unpacked with wrong size!
  2560. fi
  2561. # end of 'Sources/xcomp.c'
  2562. fi
  2563. echo shar: End of archive 1 \(of 2\).
  2564. cp /dev/null ark1isdone
  2565. MISSING=""
  2566. for I in 1 2 ; do
  2567.     if test ! -f ark${I}isdone ; then
  2568.     MISSING="${MISSING} ${I}"
  2569.     fi
  2570. done
  2571. if test "${MISSING}" = "" ; then
  2572.     echo You have unpacked both archives.
  2573.     rm -f ark[1-9]isdone
  2574. else
  2575.     echo You still need to unpack the following archives:
  2576.     echo "        " ${MISSING}
  2577. fi
  2578. ##  End of shell archive.
  2579. exit 0
  2580. -- 
  2581. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  2582. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  2583. Post requests for sources, and general discussion to comp.sys.amiga.misc.
  2584.